xSDK

May 18, 2026 · View on GitHub

A modular .NET SDK with pluggable data providers, extensible hosting, and built-in observability — designed for building production-ready services and applications.

Build Status Latest Release Quality Gate Status Unit Tests Coverage

Security Policy Dependabot Status Security Rating Vulnerabilities

Bugs Code Smells Maintainability Rating Duplicated Lines (%) Lines of Code

.NET Version pnpm Version License: Apache-2.0


Table of Contents


About

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, Consul, 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.

Technology Stack

CategoryTechnologyVersion
Runtime.NET10.0
LanguageC#latest
Web FrameworkASP.NET Core10.0
ORMEntity Framework Core10.0.5
Document DBMongoDB (EF Core provider)10.0.1
Embedded DBLiteDB / LiteDB.Async5.0.21
Flat File StoreJsonFlatFileDataStore2.4.2
Service DiscoveryConsul1.8.0
Secrets ManagementVaultSharp1.17.5.1
Plugin SystemWeikio.PluginFramework1.5.1
ValidationFluentValidation12.1.1
Object MappingMapster10.0.6
ObservabilityOpenTelemetry1.15.1
API VersioningAsp.Versioning8.1.1
API DocumentationMicrosoft.AspNetCore.OpenAPI10.0.5
Cloud EventsCloudNative.CloudEvents2.8.0
CLISpectre.Console.Cli0.53.1
HTTP ClientRestSharp114.0.0
Security MiddlewareNWebsec3.0.0
SerializationYamlDotNet16.3.0
Release Toolingsemantic-release / pnpm

Architecture

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 (Host)                          │
│        Hosting | Plugin Extensions | IO | Variables      │
└─────────────────────────┬────────────────────────────────┘

┌─────────────────────────▼────────────────────────────────┐
│               xSdk.Data (Base Data Layer)                │
│        IDataStore<T> | Repository | Fake Mode            │
└──────┬──────────┬──────────┬──────────┬─────────┬────────┘
       │          │          │          │         │
  ┌────▼───┐ ┌───▼────┐ ┌───▼────┐ ┌───▼──┐ ┌───▼────┐
  │EF Core │ │MongoDB │ │FlatFile│ │Vault │ │Consul  │
  └────────┘ └────────┘ └────────┘ └──────┘ └────────┘

┌─────────────────────────────▼────────────────────────────┐
│                    xSdk.Core (Foundation)                │
│    Primitives | Utilities | Validation | Mapping | I/O   │
└──────────────────────────────────────────────────────────┘

Core design principles:

  1. Repository Pattern: All data access is abstracted behind IDataStore<TEntity> interfaces.
  2. Dependency Injection First: Services register themselves via Add[ServiceName] extension methods.
  3. Async/Await Throughout: All I/O operations are fully async with CancellationToken propagation.
  4. Pluggable Providers: Switch data backends through configuration, not code changes.
  5. Observable by Design: OpenTelemetry instrumentation built into data and hosting layers.

Getting Started

Prerequisites

  • .NET 10 SDK (version 10.0.200 or later, see global.json)
  • just (command runner for development tasks)
  • pnpm 10.x (required for release tooling only)
  • Git

Clone and Build

git clone https://github.com/velvet-lab/xsdk.git
cd xsdk

# Restore and build all libraries
just build

Run Tests

just test

Run a Demo

# Example: console host demo
cd demos/console/host
dotnet run

Using a Library in Your Project

# 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.AspNetCore

Minimal Host Setup

using 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();

Project Structure

xsdk/
├── libs/                               # SDK library projects
│   ├── xSdk.Core/                      # Foundation: primitives, utilities, validation, mapping
│   ├── xSdk/                           # Host layer: hosting, plugin extensions, IO, variables
│   ├── xSdk.Plugin/                    # Plugin host infrastructure (IPluginHost / WebPluginHost)
│   ├── xSdk.Data/                      # Base data layer: IDataStore<T>, repository, fake mode
│   ├── xSdk.Data.EntityFramework/      # EF Core data provider
│   ├── xSdk.Data.EntityFramework.MongoDB/  # MongoDB via EF Core provider
│   ├── xSdk.Data.FlatFile/             # JSON flat-file data provider
│   ├── xSdk.Data.NoSql/                # LiteDB embedded NoSQL provider
│   ├── xSdk.Data.Vault/                # HashiCorp Vault secret provider
│   ├── xSdk.Extensions.Agents/         # MCP server plugin for AI agent integration
│   ├── xSdk.Extensions.AspNetCore/     # ASP.NET Core helpers and middleware
│   ├── xSdk.Extensions.AspNetCore.Links/  # HATEOAS-style link generation
│   ├── xSdk.Extensions.CloudEvents/    # CloudNative.CloudEvents integration
│   ├── xSdk.Extensions.Commands/       # CLI command extensions (Spectre.Console)
│   └── xSdk.Extensions.Telemetry/      # OpenTelemetry setup and configuration
├── 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
├── docs/adr/                           # Architectural Decision Records
├── think-tank/                         # Experimental / incubating features (e.g. xSdk.Data.Consul)
├── 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)

Key Features

Foundation Layer (xSdk.Core)

  • Shared primitives, utility types, and base abstractions used across all other libraries
  • Object mapping via Mapster (compile-time generated, zero-overhead)
  • FluentValidation registration helpers
  • API versioning primitives via Asp.Versioning
  • SemanticVersioning support
  • RestSharp-based HTTP client helpers

Core Hosting (xSdk)

  • SlimHost — lightweight, convention-based .NET generic host with pre-configured logging and DI
  • TestHost / TestHostFixture — helpers for integration tests
  • File system abstractions via Zio
  • Variable/placeholder resolution engine with YAML support
  • Plugin infrastructure via IPluginHost / WebPluginHost (see xSdk.Plugin)
  • OpenTelemetry integration wired into host startup

Data Abstractions (xSdk.Data)

  • Unified IDataStore<TEntity> abstraction shared by all providers
  • Repository factory and Fake/In-Memory mode for demos and tests
  • YAML-based data seeding support

Data Layer (xSdk.Data.*)

  • Entity Framework Core — SQL databases with full EF feature set, soft-delete support
  • 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
  • Consul (incubating, think-tank/) — service discovery and key/value configuration from HashiCorp Consul
  • Async-first API with CancellationToken propagation throughout

ASP.NET Core Extensions (xSdk.Extensions.AspNetCore)

  • API versioning configuration
  • Problem Details middleware integration
  • FluentValidation DI registration
  • NWebsec security headers middleware
  • API key authentication support

Observability (xSdk.Extensions.Telemetry)

  • OpenTelemetry traces, metrics, and logs in one setup call
  • OTLP exporter support (Console + gRPC/HTTP)
  • Runtime, EF Core, ASP.NET Core, HTTP, gRPC, Redis, and process instrumentation
  • Container, host, and OS resource detectors

Plugin System (xSdk.Plugin)

  • IPluginHost / WebPluginHost model — DI-registered plugin hosts participating in the normal IServiceCollection lifecycle (see ADR-027)
  • Builder-scoped SlimHost — no static singleton, full test isolation (see ADR-026)
  • Convention-based Enable* extension methods per extension package

AI Agent Integration (xSdk.Extensions.Agents)

  • MCP (Model Context Protocol) server plugin via AgentsPluginHost
  • EnableAgents() extension method on IHostBuilder

Cloud Events (xSdk.Extensions.CloudEvents)

  • CloudNative CloudEvents serialization and routing for event-driven architectures

CLI Commands (xSdk.Extensions.Commands)

  • Rich CLI application framework via Spectre.Console.Cli
  • Convention-based command registration
  • Hypermedia link generation for REST APIs following HATEOAS principles

Development Workflow

Branching Strategy

BranchPurpose
mainStable, released code
nextDefault integration branch (pre-release)
feature-*Feature development

Pull requests target the next branch. Merges to main trigger official releases.

Commit Messages

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.

CI/CD Pipelines

WorkflowTriggerDescription
unit-tests.ymlPush / PR to main, nextQuality assurance — build and test
sonar-scan.ymlPR to nextSonarCloud quality analysis
check-format.ymlPR to main, nextVerify code formatting
check-license.ymlPR to main, nextValidate license headers
lint-commits.ymlPR (opened / sync / edited)Conventional commit enforcement
lint-dotnet.ymlPR to main, next.NET code consistency scan
release.ymlPush to main, nextSemantic versioning & GitHub Release

Release Process

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-run

The version is derived from conventional commit history and NuGet packages are published automatically.


Coding Standards

All C# code in this repository follows the guidelines in .github/instructions/csharp.instructions.md. Key conventions:

Naming

ConstructConventionExample
Types, Methods, PropertiesPascalCaseDataStore, GetByIdAsync
Private fields, locals, parameterscamelCase_repository, userId
InterfacesI prefixIDataStore<T>
Generic type parametersT prefixTEntity, TContext
Async methodsAsync suffixSaveAsync, GetAllAsync

Key Rules

  • Nullable reference types are enabled project-wide — handle null correctly at API boundaries.
  • ConfigureAwait(false) must be used in all library-level async code.
  • CancellationToken must 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 .editorconfig and checked in CI.

Architecture Patterns

  • 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

Frameworks and Libraries

LibraryVersionPurpose
xunit.v33.2.2Test runner ([Fact], [Theory])
Moq4.20.72Mocking framework
Testcontainers.MongoDb4.11.0Integration tests with real containers (MongoDB, etc.)
Xunit.SkippableFact1.5.23Skip tests conditionally
Bogus35.6.5Fake data generation
Microsoft.EntityFrameworkCore.InMemory10.0.5In-memory EF Core provider for unit tests
coverlet.collector8.0.1Code coverage collection (XPlat Code Coverage)

Test Naming

MethodName_Scenario_ExpectedBehavior

Examples:

  • GetByIdAsync_WhenEntityExists_ReturnsEntity
  • SaveAsync_WithNullEntity_ThrowsArgumentNullException
  • UpdateAsync_WhenConcurrencyConflict_ThrowsDbUpdateConcurrencyException

Structure (AAA Pattern)

[Fact]
public async Task GetByIdAsync_WhenEntityExists_ReturnsEntity()
{
    var store = new InMemoryDataStore<User>();
    var user = new User { Id = "1", Name = "Alice" };
    await store.InsertAsync(user);

    var result = await store.SelectAsync("1");

    Assert.NotNull(result);
    Assert.Equal("Alice", result!.Name);
}

Running Tests

# 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.


Architectural Decision Records

All significant design decisions are documented in docs/adr/. Each ADR captures the context, decision, and consequences.

ADRTitle
ADR-001Modular Library Architecture
ADR-002Slim Host Singleton
ADR-003Plugin Extensibility Model
ADR-004Variable / Setup Configuration System
ADR-005Repository Pattern with Factory
ADR-006Provider-Agnostic Data Layer
ADR-007Entity Framework Data Provider
ADR-008NoSQL LiteDB Provider
ADR-009Flat-File JsonStore Provider
ADR-010Vault Secret Management
ADR-011MongoDB via EF Core
ADR-012Demo Fake Repository Mode
ADR-013NLog Logging Framework
ADR-014OpenTelemetry Observability
ADR-015ASP.NET Core Web Host Extension
ADR-016CloudEvents Integration
ADR-017Spectre Console Commands
ADR-018Mapster Object Mapping
ADR-019Zio Filesystem Abstraction
ADR-020Central Package Management
ADR-021SemVer Version Validation
ADR-022Weikio Plugin Framework
ADR-023ASP.NET Core Links / Hypermedia
ADR-024xSdk.Core as Unified Foundation Layer
ADR-025HashiCorp Consul as Service-Discovery and Configuration Provider

Contributing

  1. Fork the repository and create a feature branch from next.
  2. Follow the C# development guidelines.
  3. Write unit tests for all public APIs (mandatory).
  4. Ensure all XML documentation (///) is complete on public members.
  5. Run just build and just test locally before pushing.
  6. Use Conventional Commits for all commit messages.
  7. Open a pull request targeting the next branch.

Copilot / AI Guidelines

This repository ships with a full set of GitHub Copilot customizations:

ResourcePurpose
copilot-instructions.mdProject-wide coding context
.github/instructions/9 focused instruction files by topic
.github/agents/4 specialized agent modes (see below)
.github/skills/10 reusable skill modules from awesome-copilot
.github/guidance/Commit, pull request, and review guidance

Available agents:

AgentPurpose
C# ExpertSenior .NET developer — clean, idiomatic, secure C# code
GitHub Actions ExpertSecure CI/CD workflows, action SHA pinning, OIDC
ADR GeneratorCreate structured Architecture Decision Records
Technical Debt Remediation PlanAnalyze and prioritize technical debt

Security

See SECURITY.md for the full security policy and vulnerability reporting process.

Supported versions:

VersionSupported
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.


License

This project is licensed under the Apache-2.0 License — see the LICENSE file for details.

Copyright © 2026 Velvet Lab