CShells 0.0.20
dotnet add package CShells --version 0.0.20
NuGet\Install-Package CShells -Version 0.0.20
<PackageReference Include="CShells" Version="0.0.20" />
<PackageVersion Include="CShells" Version="0.0.20" />
<PackageReference Include="CShells" />
paket add CShells --version 0.0.20
#r "nuget: CShells, 0.0.20"
#:package CShells@0.0.20
#addin nuget:?package=CShells&version=0.0.20
#tool nuget:?package=CShells&version=0.0.20
CShells
A modular multi-tenancy framework for .NET that enables building feature-based applications with isolated services, configuration, and background workers.
Purpose
CShells is the core runtime package that provides blueprint-driven shell activation, cooperative drain-based reload, feature discovery, per-shell DI containers, and configuration-driven multi-tenancy.
Key Features
- Multi-shell architecture — each shell has its own isolated DI container
- Feature-based modularity — features are discovered automatically via attributes
- Dependency resolution — features can depend on other features with topological ordering
- Configuration-driven — shells and their features are configured via
appsettings.jsonor code - Generation lifecycle —
Initializing → Active → Deactivating → Draining → Drained → Disposed - Cooperative reload —
IShellRegistry.ReloadAsync(name)builds the next generation while draining the previous one; in-flight request scopes finish against the old provider - Observable events —
IShellLifecycleSubscriberreceives every state transition - Configurable drain policies — fixed, extensible, and unbounded timeouts
Installation
dotnet add package CShells
Quick Start
1. Create a Feature
using CShells.Features;
using Microsoft.Extensions.DependencyInjection;
[ShellFeature("Core", DisplayName = "Core Services")]
public class CoreFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ITimeService, TimeService>();
}
}
2. Configure Shells
{
"CShells": {
"Shells": {
"Default": {
"Features": { "Core": {} }
}
}
}
}
3. Register CShells
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddCShells(cshells =>
cshells.WithConfigurationProvider(builder.Configuration));
var app = builder.Build();
app.Run();
Shell Scopes & Background Work
IShell.BeginScope() returns a tracked IShellScope that (a) exposes a scoped IServiceProvider built from the shell's container and (b) delays drain-handler invocation while the scope is outstanding:
public class ShellBackgroundWorker(IShellRegistry registry) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
foreach (var name in registry.GetBlueprintNames())
{
var shell = registry.GetActive(name);
if (shell is null) continue;
await using var scope = shell.BeginScope();
var service = scope.ServiceProvider.GetService<IMyService>();
service?.Execute();
}
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
}
}
}
Code-First Shell Registration
builder.Services.AddCShells(cshells =>
{
cshells.AddShell("Default", shell => shell
.WithFeatures("Core", "Weather")
.WithConfiguration("Theme", "Dark")
.WithConfiguration("MaxItems", "100"));
});
Per-Shell Initialization & Drain
Register IShellInitializer services for per-shell startup work and IDrainHandler services for cooperative shutdown:
public class PaymentsFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IPaymentProcessor, StripePaymentProcessor>();
services.AddTransient<IShellInitializer, PaymentsInitializer>();
services.AddTransient<IDrainHandler, PaymentsDrainHandler>();
}
}
Initializers run sequentially in DI-registration order during Initializing → Active. Drain handlers run in parallel during Draining, after all outstanding IShellScope handles have been released (or the drain deadline elapses).
Reload
var result = await registry.ReloadAsync("payments");
// result.NewShell.Descriptor.Generation == previous + 1
// result.Drain (when non-null) is the cooperative drain on the previous generation.
if (result.Drain is not null)
await result.Drain.WaitAsync();
Learn More
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CShells.Abstractions (>= 0.0.20)
- JetBrains.Annotations (>= 2025.2.4)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.DependencyModel (>= 10.0.1)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
-
net8.0
- CShells.Abstractions (>= 0.0.20)
- JetBrains.Annotations (>= 2025.2.4)
- Microsoft.Extensions.Configuration (>= 9.0.11)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.11)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.11)
- Microsoft.Extensions.DependencyInjection (>= 9.0.11)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.11)
- Microsoft.Extensions.DependencyModel (>= 10.0.1)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.11)
- Microsoft.Extensions.Logging (>= 9.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.11)
-
net9.0
- CShells.Abstractions (>= 0.0.20)
- JetBrains.Annotations (>= 2025.2.4)
- Microsoft.Extensions.Configuration (>= 9.0.11)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.11)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.11)
- Microsoft.Extensions.DependencyInjection (>= 9.0.11)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.11)
- Microsoft.Extensions.DependencyModel (>= 10.0.1)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.11)
- Microsoft.Extensions.Logging (>= 9.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.11)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on CShells:
| Package | Downloads |
|---|---|
|
CShells.AspNetCore
ASP.NET Core integration for CShells. Provides middleware and extensions for shell/tenant resolution based on HTTP context, including host-based and route-based strategies for modular multi-tenant applications. |
|
|
CShells.Providers.FluentStorage
FluentStorage integration provider for CShells. Enables loading and persisting shell configurations from various storage backends (Azure Blob, AWS S3, disk, memory, etc.) supported by FluentStorage. |
|
|
Elsa.Shells.Api
Provides API endpoints for shell management. |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on CShells:
| Repository | Stars |
|---|---|
|
elsa-workflows/elsa-core
The Workflow Engine for .NET
|
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.20 | 40 | 5/8/2026 |
| 0.0.19 | 57 | 5/6/2026 |
| 0.0.18 | 169 | 5/2/2026 |
| 0.0.17 | 165 | 4/29/2026 |
| 0.0.16 | 175 | 4/27/2026 |
| 0.0.15 | 162 | 4/27/2026 |
| 0.0.14 | 459 | 4/20/2026 |
| 0.0.13 | 158 | 4/17/2026 |
| 0.0.12 | 237 | 3/16/2026 |
| 0.0.11 | 283 | 2/28/2026 |
| 0.0.10 | 173 | 2/24/2026 |
| 0.0.9 | 391 | 2/15/2026 |
| 0.0.8 | 173 | 2/13/2026 |
| 0.0.7 | 181 | 2/9/2026 |
| 0.0.6 | 190 | 1/18/2026 |
| 0.0.5 | 308 | 12/18/2025 |
| 0.0.4 | 203 | 12/5/2025 |
| 0.0.3 | 225 | 12/3/2025 |
| 0.0.2 | 686 | 12/1/2025 |
| 0.0.1 | 141 | 11/29/2025 |