PowerCSharp.BuiltInFeatures ships one feature today: CORS, FeatureKey = "Cors", Order => 10, disabled by default. It's gated by runtime flag, not by package reference — the bundle ships as a whole, so you can't just "not reference it" to get rid of one built-in.
That's the reason the replace pattern exists, and it's intentional, not a workaround:
// Step 1 — disable the built-in
{ "PowerFeatures": { "Cors": { "Enabled": false } } }
// Step 2 — register your own module with the same FeatureKey, after the built-ins
builder.Services.AddPowerFeatures(builder.Configuration, options =>
{
options.AddBuiltInFeatures();
options.AddModule(new MyCustomCorsModule()); // FeatureKey = "Cors"
});
Two modules sharing a FeatureKey resolve last-registration-wins, by design. Get the order backwards and your custom module silently loses to the built-in one — worth double-checking if a "replacement" doesn't seem to be taking effect.
Why not just make built-ins reference-gated like everything else? Because CORS, and whatever else lands in this bundle, has zero third-party dependencies and no backend to swap — the pluggable Feature.<Name> model exists for capabilities that genuinely have more than one implementation worth choosing between. This bundle is for the ones that don't.
One honest note on where the bundle is headed: the package's own roadmap section lists CorrelationId, SecurityHeaders, ExceptionHandling, and HealthChecks as planned — meaning direction, not a date. Sanitization was on an earlier version of that same list and ended up shipping as its own pluggable Feature.Sanitization package instead. Roadmaps move; I'd rather say so than let a stale list imply more than what's actually built.
Top comments (0)