marcinbor85 /
microshell
MicroShell is a lightweight pure C implementation of shell emulator dedicated for embedded bare-metal systems.
Loading repository data…
valence-works / repository
A lightweight shell & feature system for ASP.NET Core that lets you build modular and multi-tenant apps with per-shell DI containers and config-driven features.
A lightweight, extensible shell and feature system for .NET projects that lets you build modular and multi-tenant apps with per-shell DI containers and config-driven features.
CShells is useful whenever you want clear modular boundaries, configurable feature sets, and isolated dependency graphs inside a .NET application.
Model each functional area (e.g., Core, Billing, Reporting) as a feature and group them into shells that can be enabled or disabled via configuration. This keeps a monolithic codebase modular and lets you turn features on or off without code changes.
Treat each tenant as a shell with its own configuration and feature set. You can roll out features gradually, offer different capabilities per tenant, and keep tenant-specific services (e.g., integrations, branding, limits) isolated in per-shell DI containers.
Use shells to represent different plans (Basic, Pro, Enterprise) or environments (Development, Staging, Production), each enabling a different set of features. This lets you keep one codebase while varying behavior and dependencies based on environment, subscription level, or other criteria.
Build your own modular application framework where modules are implemented as features discovered at startup. CShells’ feature discovery and ordering, combined with per-shell DI, make it a good fit for CMSs, CRMs, ERP-style systems, and frameworks similar to Orchard Core or ABP.
Model each brand or deployment as a shell with its own enabled features, configuration, and DI registrations. You can share the same core features while varying branding, integrations, or compliance-related components per shell.
Expose extension points as features that can be discovered from additional assemblies and loaded into shells. This enables plugin-style architectures where internal teams or third parties can add capabilities without modifying the core app.
Use shells to represent different API surfaces (mobile, web, partner, admin) with their own middleware, endpoints, and policies. Each shell can have tailored dependencies and configuration while still sharing common infrastructure and hosting.
Introduce CShells into an existing application and start moving functionality into features and shells incrementally. This allows you to modularize and isolate areas of a legacy system over time without a big-bang rewrite.
CShells provides multiple NuGet packages for different use cases:
| Package | Description | When to Use |
|---|---|---|
| CShells.Abstractions | Core interfaces and models (IShellFeature, ShellSettings, ShellId) | Reference this in feature class libraries to avoid depending on the full framework |
| CShells.AspNetCore.Abstractions | ASP.NET Core interfaces (IWebShellFeature) | Reference this in ASP.NET Core feature class libraries for web endpoint support |
| CShells | Core framework implementation | Reference this in your main application project |
| CShells.AspNetCore | ASP.NET Core integration (middleware, routing, resolvers) | Reference this in your ASP.NET Core application project |
| CShells.Providers.FluentStorage | FluentStorage-based shell configuration provider | Use when loading shell configurations from disk, cloud storage, etc. |
YourSolution/
├── src/
│ ├── YourApp/ # Main ASP.NET Core application
│ │ └── YourApp.csproj # References: CShells, CShells.AspNetCore, YourApp.Features
│ └── YourApp.Features/ # Feature definitions library
│ └── YourApp.Features.csproj # References: CShells.AspNetCore.Abstractions only
This structure allows your feature library to remain lightweight with minimal dependencies, while your main application references the full CShells implementation.
Features implement IShellFeature for service registration:
using CShells.Features;
using Microsoft.Extensions.DependencyInjection;
public class CoreFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ITimeService, TimeService>();
}
}
For ASP.NET Core applications with HTTP endpoints, implement IWebShellFeature:
using CShells.AspNetCore.Features;
using Microsoft.Extensions.DependencyInjection;
public class ApiFeature : IWebShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IApiService, ApiService>();
}
public void MapEndpoints(IEndpointRouteBuilder endpoints, IHostEnvironment? environment)
{
endpoints.MapGet("api/status", () => new { Status = "OK" });
}
}
Best Practice: Define your features in a separate class library that only references CShells.Abstractions (or CShells.AspNetCore.Abstractions for web features). This keeps your feature definitions lightweight and independent of the full framework implementation.
The [ShellFeature] attribute is optional. Use it only when you need to:
using CShells.Features;
// Without attribute - feature name is "WeatherFeature" (derived from class name)
public class WeatherFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IWeatherService, WeatherService>();
}
}
// With attribute - explicit name "Weather", display name, and string-based dependency
[ShellFeature("Weather", DisplayName = "Weather API", DependsOn = ["Core"])]
public class WeatherFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IWeatherService, WeatherService>();
}
}
// Strongly-typed dependency - the feature name is resolved from CoreFeature's attribute
[ShellFeature("Weather", DisplayName = "Weather API", DependsOn = [typeof(CoreFeature)])]
public class WeatherFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IWeatherService, WeatherService>();
}
}
// Mixed - combine string and type-based dependencies
[ShellFeature("Weather", DisplayName = "Weather API", DependsOn = [typeof(CoreFeature), "Logging"])]
public class WeatherFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IWeatherService, WeatherService>();
}
}
Note: When using
typeof(SomeFeature)inDependsOn, the type must implementIShellFeature. The feature name is resolved from the target type's[ShellFeature]attribute (or derived from the class name if no attribute is present), so renaming the attribute automatically updates all dependents.
Features can access shell configuration via IConfiguration (resolved from the shell's service provider):
using CShells;
using CShells.Features;
using Microsoft.Extensions.Configuration;
public class WeatherFeature : IShellFeature
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IWeatherService>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
var apiKey = config["Weather:ApiKey"];
return new WeatherService(apiKey);
});
}
}
Option A: Using appsettings.json (default section name: CShells):
{
"CShells": {
"Shells": {
"Default": {
"Features": {
"Core": true,
"Weather": true
},
"Configuration": {
"WebRouting": {
"Path": ""
}
}
},
"Admin": {
"Features": {
"Core": true,
"Admin": { "MaxUsers": 100, "EnableAuditLog": true }
},
"Configuration": {
"WebRouting": {
"Path": "admin",
"RoutePrefix": "api/v1"
}
}
}
}
}
}
Shell names are the keys under CShells:Shells. This makes overrides stable, for example:
CSHELLS__SHELLS__DEFAULT__FEATURES__WEATHER__APIKEY=...
Use PascalCase shell names in JSON, such as Default or MyShell; environment variable keys are commonly written in uppercase.
You can also override the configuration section name via builder.AddShells("MySection").
Option B: Using JSON files with FluentStorage:
Create JSON files in a Shells folder (e.g., Default.json, Admin.json):
{
"Name": "Default",
"Features": {
"Core": true,
"Weather": true
},
"Configuration": {
"WebRouting": {
"Path": ""
}
}
}
Then configure the provider:
using FluentStorage;
using CShells.Providers.FluentStorage;
var builder = WebApplication.CreateBuilder(args);
var shellsPath = Path.Combine(builder.Environment.ContentRootPath, "Shells");
var blobStorage = StorageFactory.Blobs.DirectoryFiles(shellsPath);
builder.AddShells(cshells =>
{
cshells.WithFluentStorageProvider(blobStorage);
});
Option C: Code-first configuration:
builder.AddShells(cshells =>
{
cshells.AddShell("Default", shell => shell
.WithFeatures("Core", "Weather")
.WithConfiguration("WebRouting:Path", ""));
cshells.AddShell("Admin", shell => shell
.WithFeature("Core")
.WithFeature("Admin", settings => settings
.WithSetting("MaxUsers", 100)
.WithSetting("EnableAuditLog", true))
.WithConfiguration("WebRouting:Path", "admin")
.WithConfiguration("WebRouting:RoutePrefix", "api/v1"));
});
Simple setup (reads from appsettings.json):
var builder = WebApplication.CreateBuilder(args);
// Register CShells from configuration (default section: CShells)
// Uses the host-derived default feature assembly set
builder.AddShells();
var app = builder.Build();
// Configure middleware and endpoints for all shells
app.MapShells();
app.Run();
To switch to explicit feature assembly selection, configure it fluently on CShellsBuilder:
Use WithAssemblies(...) and WithHostAssemblies() to select which assemblies feature discovery should scan, and `WithAssem
Selected from shared topics, language and repository description—not editorial ratings.
marcinbor85 /
MicroShell is a lightweight pure C implementation of shell emulator dedicated for embedded bare-metal systems.
RonIovine /
A Lightweight, Process-Specific, Embedded Command Line Shell/CLI for C/C++/Python/Go Applications
hoangsonww /
⚙️ A lightweight C-based task VM with content-addressed storage, automatic incremental caching, and terminal-visible dependency graphs; parallel-capable, polyglot (Go, Rust, Python, Node.js, Ruby, assembly) workflow engine with Docker support for reproducible pipelines.
bocaletto-luca /
Remote-Cmd is a lightweight client-server app written in C that lets you securely execute remote shell commands with authentication, syslog logging, optional system update, IPv4/IPv6 support, and dry-run mode. Designed for Linux Debian environments with zero external dependencies.
johnb-xp /
A lightweight shell for Microsoft Windows made with C# and Visual Basic
gragero /
OJC-shell OJC-shell is a lightweight, minimal, and extensible Unix-like shell written in pure C — designed as the first building block of the OJclicks OS vision