| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [View Raw Code] [Original HTTPS Page] |
Status: Architecture specification. Defines the Feature & Feature-Flag mechanism for PowerCSharp: how reusable capabilities are packaged, discovered, gated (build-time + runtime), configured, and registered into a host application's DI container and request pipeline.
The Features system turns reusable capabilities (cache, sanitization, observability, third-party integrations, etc.) into self-contained, toggleable units so that every application can compose exactly the capabilities it needs — nothing more.
| Tier | Name | Packaging | Gating | Third-party deps |
|---|---|---|---|---|
| Group 1 | Built-in Features | One bundle package (PowerCSharp.BuiltInFeatures) | Runtime flag only | None isolated — only framework/ASP.NET Core |
| Group 2 | Pluggable Features | One package (or family) each (PowerCSharp.Feature.<Name>) | Two-layer: package reference + runtime flag | Isolated per package |
Built-in Features are lightweight ASP.NET Core / pipeline / app capabilities (CORS, correlation ID, exception handling, security headers, health checks, sanitization, JWT wiring). They ship together and are toggled purely at runtime.
Pluggable Features are complex and/or third-party-bearing capabilities (Cache, Sitecore, Sentry, OpenTelemetry, AWS Secrets). Each is its own package so its dependencies only enter an app that explicitly references it.
Any Built-in Feature can be disabled and replaced by a custom Pluggable Feature — e.g. ship your own JWT or sanitization feature and turn off the built-in one.
PowerCSharp.Features.Abstractions contracts only, zero third-party deps PowerCSharp.Features engine: discovery, flag resolution, DI orchestration, diagnostics PowerCSharp.BuiltInFeatures Group 1 bundle (depends on engine + Microsoft.AspNetCore.App) PowerCSharp.Feature.Cache.Abstractions Group 2 — cache contracts + NoOp floors (no third-party, netstandard2.0 + net8.0) PowerCSharp.Feature.Cache Group 2 — module + options + ASP.NET Core wiring (net8.0) PowerCSharp.Feature.Cache.BitFaster Group 2 — BitFaster-backed implementation (isolates BitFaster.Caching) PowerCSharp.Feature.Cache.Disk Group 2 — disk-backed LRU implementation (no third-party) # future: PowerCSharp.Feature.Cache.Memory native MemoryCache implementation PowerCSharp.Feature.Sitecore third-party GraphQL integration PowerCSharp.Feature.Sentry third-party APM PowerCSharp.Feature.Observability OpenTelemetry
PowerCSharp.Features.Abstractions (contracts, no deps)
▲ ▲
│ │
PowerCSharp.Features (engine) │
▲ ▲ │
│ │ │
PowerCSharp.BuiltInFeatures PowerCSharp.Feature.Cache (module/options)
(Group 1: bundle) ▲ ▲
│ │
│ │
PowerCSharp.Feature.Cache.Abstractions (cache contracts + NoOp)
▲ ▲
│ │
PowerCSharp.Feature.Cache.BitFaster PowerCSharp.Feature.Cache.Disk
(impl, isolates BitFaster) (disk LRU impl)
All features MAY also depend on existing libraries:
PowerCSharp.Core / .Extensions / .Helpers / .Utilities
Namespace note: because the package name is PowerCSharp.Feature.Cache.Abstractions, the contract namespaces are PowerCSharp.Feature.Cache.Abstractions, PowerCSharp.Feature.Cache.Abstractions.Enums, and PowerCSharp.Feature.Cache.Abstractions.NoOp. They are not under PowerCSharp.Feature.Cache.
Conceptual shapes (names indicative; see the Authoring Guide for usage).
The unit a feature implements to self-register.
public interface IFeatureModule
{
string FeatureKey { get; } // stable identifier, e.g. "Cache"
int Order { get; } // registration + middleware ordering (lower runs first)
void ConfigureServices(IFeatureRegistrationContext context); // DI registration
void ConfigurePipeline(IFeaturePipelineContext context); // optional middleware (mostly Group 1)
}Passed to ConfigureServices; wraps the wiring surface.
Passed to ConfigurePipeline; wraps IApplicationBuilder and resolved services.
Flag access — not boolean-only. Supports typed variants/values from day one.
public interface IFeatureFlagProvider
{
bool IsEnabled(string featureKey);
FeatureFlagValue GetValue(string featureKey); // typed variant: string/enum/number
ValueTask<bool> IsEnabledAsync(string featureKey, CancellationToken ct = default);
ValueTask<FeatureFlagValue> GetValueAsync(string featureKey, CancellationToken ct = default);
}FeatureFlagValue exposes typed accessors (AsBoolean(), AsString(), AsEnum<T>(), AsInt32(), …) plus the source that produced it (for diagnostics).
Base for a feature's typed options bound from its config section; always carries Enabled.
public abstract class FeatureOptionsBase
{
public bool Enabled { get; set; }
}Metadata for the registry/diagnostics: Key, DisplayName, Tier (BuiltIn/Pluggable), DefaultEnabled, PackageId, Version.
Two registration styles are supported; a feature author picks the one that suits its nature (or supports both).
Discovery is opt-in per assembly — the host declares which assemblies to scan in AddPowerFeatures(...), so nothing is registered by surprise.
Pluggable Features (Group 2) are gated by two independent layers; both must pass for a feature to run.
If the host does not reference PowerCSharp.Feature.<Name> (and its .Provider impl), the module type and all of its third-party dependencies are simply absent from the dependency tree — zero code, zero transitive packages. This is the primary isolation mechanism.
If a feature package is referenced but its flag is off, the module is discovered but its ConfigureServices is skipped. Where dependents need a binding regardless, the feature registers a NoOp implementation so resolution stays safe (mirrors the proven NoOpDiskCacheService fallback pattern from the source project).
Reference package? Flag enabled? Result
No — Absent: no code, no deps
Yes No Discovered, skipped; optional NoOp registered
Yes Yes Active: ConfigureServices + ConfigurePipeline run
Built-in Features use Layer 2 only — they always ship in the bundle and are runtime-toggled.
{
"PowerFeatures": {
"Cache": { "Enabled": true, "Provider": "BitFaster", "Capacity": 1000 },
"Sitecore": { "Enabled": false }
}
}See PowerCSharp.Features.FlagReference.md for the full schema, precedence rules, and provider integration.
// Program.cs
builder.Services
.AddPowerFeatures(builder.Configuration, options =>
{
options.ScanAssemblies(typeof(CacheFeatureModule).Assembly); // opt-in auto-discovery
options.Override("Cache", true); // optional explicit override
options.EnableDiagnosticsEndpoint(); // opt-in, off by default
})
.AddCacheFeature(builder.Configuration); // optional explicit Group-2 registration
var app = builder.Build();
app.UsePowerFeatures(); // applies enabled features' middleware in OrderAddPowerFeatures:
UsePowerFeatures:
In scope from the first release:
This visibility is especially valuable for the public Clean Architecture template, where consumers need to see exactly which features are active.
| Back | FazBrowse Home | New Git URL |