A modular .NET SDK with pluggable data providers, extensible hosting, and built-in observability — designed for building production-ready services and applications.
- About
- Technology Stack
- Architecture
- Getting Started
- Project Structure
- Key Features
- Development Workflow
- Coding Standards
- Testing
- Contributing
- Security
- License
xSDK is a modular SDK library for .NET that provides a collection of reusable building blocks for data access, hosting, extensibility, and observability. It abstracts common infrastructure concerns — such as database providers, file storage, secrets management, and telemetry — behind clean, consistent interfaces, letting application teams focus on domain logic.
Key goals:
- Pluggable data providers: Swap between Entity Framework Core, MongoDB, LiteDB, FlatFile, or Vault-based storage without changing application code.
- Opinionated hosting: A slim, convention-based host that wires up DI, logging, and configuration with minimal boilerplate.
- Extensibility: Plugin infrastructure and extension points for custom scenarios.
- Observability: First-class OpenTelemetry integration for metrics, traces, and logs.
| Category | Technology | Version |
|---|---|---|
| Runtime | .NET | 10.0 |
| Language | C# | 13 (latest) |
| Web Framework | ASP.NET Core | 10.0 |
| ORM | Entity Framework Core | 10.0.5 |
| Document DB | MongoDB (EF Core provider) | 10.0.1 |
| Embedded DB | LiteDB / LiteDB.Async | 5.0.21 |
| Flat File Store | JsonFlatFileDataStore | 2.4.2 |
| Secrets Management | VaultSharp | 1.17.5.1 |
| Plugin System | Weikio.PluginFramework | 1.5.1 |
| Validation | FluentValidation | 12.1.1 |
| Object Mapping | Mapster | 7.4.0 |
| Logging | NLog | 6.1.1 |
| Observability | OpenTelemetry | 1.15.0 |
| API Versioning | Asp.Versioning | 8.1.1 |
| API Documentation | Microsoft.AspNetCore.OpenAPI | 10.0.5 |
| Cloud Events | CloudNative.CloudEvents | 2.8.0 |
| CLI | Spectre.Console.Cli | 0.53.1 |
| HTTP Client | RestSharp | 114.0.0 |
| Security Middleware | NWebsec | 3.0.0 |
| Release Tooling | semantic-release / pnpm | — |
xSDK follows a modular, layered architecture where each library is independently consumable:
┌──────────────────────────────────────────────────────────┐
│ Application Layer │
│ (demos/, ASP.NET Core APIs, Console Apps) │
└─────────────────────────┬────────────────────────────────┘
│
┌─────────────────────────▼────────────────────────────────┐
│ xSdk.Extensions.* │
│ AspNetCore | AspNetCore.Links | CloudEvents | │
│ Commands | Telemetry │
└─────────────────────────┬────────────────────────────────┘
│
┌─────────────────────────▼────────────────────────────────┐
│ xSdk (Core) │
│ Hosting | Plugin Extensions | IO | Variables │
└──────┬────────────┬───────────┬────────────┬─────────────┘
│ │ │ │
┌─────▼──┐ ┌─────▼───┐ ┌────▼────┐ ┌─────▼──────┐
│EF Core │ │MongoDB │ │FlatFile │ │ Vault │
│xSdk │ │xSdk │ │xSdk │ │ xSdk │
│.Data. │ │.Data. │ │.Data. │ │ .Data. │
│Entity- │ │Entity- │ │FlatFile │ │ Vault │
│Frame- │ │Frame- │ └─────────┘ └────────────┘
│work │ │work. │
└────────┘ │MongoDB │
└─────────┘
Core design principles:
- Repository Pattern: All data access is abstracted behind
IDataStore<TEntity>interfaces. - Dependency Injection First: Services register themselves via
Add[ServiceName]extension methods. - Async/Await Throughout: All I/O operations are fully async with
CancellationTokenpropagation. - Pluggable Providers: Switch data backends through configuration, not code changes.
- Observable by Design: OpenTelemetry instrumentation built into data and hosting layers.
- .NET 10 SDK (version
10.0.200or later, seeglobal.json) - just (command runner for development tasks)
- pnpm 10.x (required for release tooling only)
- Git
git clone https://github.com/velvet-lab/xsdk.git
cd xsdk
# Restore and build all libraries
just buildjust test# Example: console host demo
cd demos/console/host
dotnet run# Core SDK
dotnet add package xSdk
# Entity Framework data provider
dotnet add package xSdk.Data.EntityFramework
# ASP.NET Core extensions
dotnet add package xSdk.Extensions.AspNetCoreusing Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using xSdk.Hosting;
var host = Host
.CreateBuilder(args, "my-app", "my-company", "ma")
.ConfigureServices((context, services) =>
{
services.AddMyService();
})
.Build();
await host.RunAsync();xsdk/
├── libs/ # SDK library projects
│ ├── xSdk/ # Core SDK (hosting, plugin extensions, IO)
│ ├── xSdk.Data.EntityFramework/ # EF Core data provider
│ ├── xSdk.Data.EntityFramework.MongoDB/ # MongoDB via EF Core
│ ├── xSdk.Data.FlatFile/ # JSON flat-file data provider
│ ├── xSdk.Data.NoSql/ # LiteDB NoSQL provider
│ ├── xSdk.Data.Vault/ # HashiCorp Vault secret provider
│ ├── xSdk.Extensions.AspNetCore/ # ASP.NET Core helpers
│ ├── xSdk.Extensions.AspNetCore.Links/ # HATEOAS-style link generation
│ ├── xSdk.Extensions.CloudEvents/ # CloudNative.CloudEvents integration
│ ├── xSdk.Extensions.Commands/ # CLI command extensions
│ ├── xSdk.Extensions.Telemetry/ # OpenTelemetry setup
│ └── xSdk.Plugin/ # Plugin infrastructure
├── demos/ # Sample applications
│ ├── console/ # Basic console host demo
│ ├── datalayer-entityframework/ # EF Core demo
│ ├── datalayer-flatfile/ # Flat-file storage demo
│ ├── datalayer-mongodb/ # MongoDB demo
│ ├── datalayer-nosql/ # LiteDB demo
│ ├── datalayer-vault/ # Vault demo
│ ├── host/ # Generic host demo
│ ├── plugin/ # Plugin system demo
│ ├── telemetry/ # OpenTelemetry demo
│ └── webapi/ # ASP.NET Core Web API demo
├── think-tank/ # Experimental features (Consul, Mermaid, Package)
├── tools/ # Build and generator tools
├── Directory.Build.props # Shared MSBuild properties
├── Directory.Build.targets # Shared MSBuild targets
├── Directory.Packages.props # Central NuGet package version management
├── global.json # .NET SDK version pin
├── xsdk.sln # Main solution file
└── xsdk-demos.sln # Demos solution file
Each library under libs/ follows the same layout:
libs/xSdk.SomeLibrary/
├── src/ # Production code
└── tests/ # Unit tests (mirrors src structure)
SlimHost— lightweight, convention-based .NET generic host with pre-configured logging and DITestHost/TestHostFixture— helpers for integration tests- File system abstractions via
Zio - Variable/placeholder resolution engine
- Plugin extension points
- Unified
IDataStore<TEntity>abstraction across all providers - Entity Framework Core — SQL databases with full EF feature set
- MongoDB — document store via the official EF Core MongoDB provider
- LiteDB — embedded, serverless NoSQL database (async variant included)
- FlatFile — JSON file-based storage for simple scenarios
- Vault — read secrets and configuration from HashiCorp Vault
- Async-first API with
CancellationTokenpropagation throughout
- API versioning configuration
- Problem Details middleware integration
- FluentValidation DI registration
- NWebsec security headers middleware
- API key authentication support
- OpenTelemetry traces, metrics, and logs in one setup call
- OTLP exporter support
- Runtime, EF Core, and process instrumentation
- Dynamically load and host plugins using
Weikio.PluginFramework - Convention-based plugin discovery
- CloudNative CloudEvents serialization and routing for event-driven architectures
| Branch | Purpose |
|---|---|
main |
Stable, released code |
next |
Default integration branch (pre-release) |
feature-* |
Feature development |
Pull requests target the next branch. Merges to main trigger official releases.
This project uses Conventional Commits enforced by lint-commits CI workflow. Commit messages must follow the format:
<type>(<scope>): <description>
feat(data): add LiteDB async support
fix(hosting): resolve null reference in SlimHost startup
docs(readme): update getting started section
Common types: feat, fix, docs, test, refactor, chore, perf.
| Workflow | Trigger | Description |
|---|---|---|
unit-tests.yml |
Push / PR to main, next |
Build and run all unit tests |
sonar-scan.yml |
PR to main, next |
SonarCloud quality analysis |
mega-linter.yml |
Push / PR | Lint all file types |
check-format.yml |
Push / PR | Verify code formatting |
lint-commits.yml |
PR | Conventional commit enforcement |
release.yml |
Push to main, next |
Semantic versioning & GitHub Release |
Releases are fully automated via semantic-release:
# Install Node.js dependencies (for release tooling)
pnpm install
# Dry-run to preview the next release
pnpm exec semantic-release --dry-runThe version is derived from conventional commit history and NuGet packages are published automatically.
All C# code in this repository follows the guidelines in .github/instructions/csharp.instructions.md. Key conventions:
| Construct | Convention | Example |
|---|---|---|
| Types, Methods, Properties | PascalCase | DataStore, GetByIdAsync |
| Private fields, locals, parameters | camelCase | _repository, userId |
| Interfaces | I prefix |
IDataStore<T> |
| Generic type parameters | T prefix |
TEntity, TContext |
| Async methods | Async suffix |
SaveAsync, GetAllAsync |
- Nullable reference types are enabled project-wide — handle
nullcorrectly at API boundaries. ConfigureAwait(false)must be used in all library-level async code.CancellationTokenmust be accepted and passed through in every async method.- One type per file, file name matches the type name.
ArgumentNullException.ThrowIfNull()for parameter validation at public entry points.- Line length target: 120 characters.
- Code formatting is enforced via
.editorconfigand checked in CI.
- Register services via
Add[ServiceName]extension methods. - Prefer constructor injection; avoid service locator pattern.
- Use the Options pattern (
IOptions<T>) for configuration. - Follow the repository pattern for all data access.
For full details see the instruction files in .github/instructions/.
Testing follows the guidelines in .github/instructions/testing.instructions.md.
| Library | Purpose |
|---|---|
| xUnit | Test runner ([Fact], [Theory]) |
| Moq | Mocking framework |
| Testcontainers | Integration tests with real containers (MongoDB, etc.) |
Xunit.SkippableFact |
Skip tests conditionally |
Bogus |
Fake data generation |
Microsoft.EntityFrameworkCore.InMemory |
In-memory EF Core provider for unit tests |
MethodName_Scenario_ExpectedBehavior
Examples:
GetByIdAsync_WhenEntityExists_ReturnsEntitySaveAsync_WithNullEntity_ThrowsArgumentNullExceptionUpdateAsync_WhenConcurrencyConflict_ThrowsDbUpdateConcurrencyException
[Fact]
public async Task GetByIdAsync_WhenEntityExists_ReturnsEntity()
{
var store = new InMemoryDataStore<User>();
var user = new User { Id = "1", Name = "Alice" };
await store.AddAsync(user);
var result = await store.GetByIdAsync("1");
result.Should().NotBeNull();
result!.Name.Should().Be("Alice");
}# All tests
just test
# Specific project
dotnet test libs/xSdk/tests/
# With coverage
dotnet test xsdk.sln --collect:"XPlat Code Coverage"Test projects are named [ProjectName].Tests and mirror the source project structure. Tests must be independent and runnable in any order.
- Fork the repository and create a feature branch from
next. - Follow the C# development guidelines.
- Write unit tests for all public APIs (mandatory).
- Ensure all XML documentation (
///) is complete on public members. - Run
just buildandjust testlocally before pushing. - Use Conventional Commits for all commit messages.
- Open a pull request targeting the
nextbranch.
This repository ships with a full set of GitHub Copilot customizations:
| Resource | Purpose |
|---|---|
| copilot-instructions.md | Project-wide coding context |
| .github/instructions/ | Focused instruction files by topic |
| .github/prompts/ | Reusable prompt templates |
| .github/agents/ | Specialized agent modes (Architect, Reviewer, Debugger) |
Use the Architect agent for design decisions, Reviewer for code reviews, and Debugger for diagnosing issues.
See SECURITY.md for the full security policy and vulnerability reporting process.
Supported versions:
| Version | Supported |
|---|---|
| 1.1.x | ✅ |
| < 1.1.0 | ❌ |
To report a vulnerability, use GitHub's private vulnerability reporting or email danlorb@velvet-lab.net. Do not open public GitHub issues for security vulnerabilities.
This project is licensed under the Apache-2.0 License — see the LICENSE file for details.
Copyright © 2026 Velvet Lab