Features engine · v1.0.2

Ship the code once. Turn capabilities on and off with config.

A discovery-and-DI orchestration engine: capabilities register themselves as toggleable modules, resolved through one composite flag system, with startup diagnostics built in.

$ dotnet add package PowerCSharp.Features
Discovery

Nothing is scanned unless you say so

Discovery is opt-in per assembly via options.ScanAssemblies(...) — a deliberate anti-surprise-registration design. A feature author can support auto-discovery via IFeatureModule reflection, explicit services.Add<Name>Feature() calls, or both at once.

Program.cs
builder.Services.AddPowerFeatures(builder.Configuration, options =>
{
    options.AddBuiltInFeatures();          // opt-in the built-in bundle (CORS, etc.)
    options.ScanAssemblies(                // opt-in pluggable feature assemblies
        typeof(CacheFeatureModule).Assembly);
    options.Override("Cache", true);       // optional code-level override
    options.EnableDiagnosticsEndpoint();   // GET /power-features — off by default
});

var app = builder.Build();
app.UsePowerFeatures();
Composite flag resolution

One precedence chain, every feature obeys it

Code override beats a custom provider, which beats environment variables, which beats appsettings, which beats the feature's own default. Flags aren't boolean-only either — GetValue(key) returns a typed value with AsBoolean(), AsString(), AsEnum<T>(), and AsInt32() accessors.

Resolution order, highest precedence first

Code override

options.Override(key, value)

Custom provider

IFeatureFlagProvider

Environment variable

POWERFEATURES__KEY__ENABLED

appsettings.json

PowerFeatures:Key:Enabled

Feature default

FeatureDescriptor.DefaultEnabled

Modules & diagnostics

Every module looks the same to the engine

A FeatureRegistry (singleton in DI) records each module's key, tier, order, resolved enabled state, source, package ID, and version. Diagnostics are opt-in-safe: a structured startup log plus an HTTP endpoint at GET /power-features, off by default.

IFeatureModule.cs
public interface IFeatureModule
{
    string FeatureKey { get; }   // stable identifier, e.g. "Cache"
    int Order { get; }           // registration + middleware ordering

    void ConfigureServices(IFeatureRegistrationContext context);
    void ConfigurePipeline(IFeaturePipelineContext context); // optional
}

Naming that encodes the architecture

Plural Features is the framework. BuiltInFeatures is the one bundled tier. Singular Feature.<Name> is a pluggable module, and Feature.<Name>.<Provider> is a swappable backend — matching .NET convention.