🚦 Feature flags in .NET without the chaos → meet Microsoft.FeatureManagement (aka the “FeatureManagement” NuGet package)
Shipping a feature shouldn’t mean:
- deploying late at night
- praying nothing breaks
- or keeping a 6-month-long “WIP” branch 😅
With Microsoft.FeatureManagement you can turn features on/off at runtime using a consistent API + ASP.NET Core integrations.
✅ What it gives you
- A clean way to define flags (config, Azure App Configuration, etc.)
- Code-level gating via
IFeatureManager(no “if spaghetti”) - ASP.NET Core gating with
[FeatureGate]for controllers/pages/endpoints - Feature filters for real rollouts (targeting, time window, percentages)
⚡ Quick setup (ASP.NET Core)
Install:
Microsoft.FeatureManagementMicrosoft.FeatureManagement.AspNetCore
appsettings.json
{
"FeatureManagement": {
"NewCheckout": true
}
}
Program.cs
builder.Services.AddFeatureManagement();
Use it in code
app.MapGet("/checkout", async (IFeatureManager fm) => { if (await fm.IsEnabledAsync("NewCheckout")) return Results.Ok("✅ New checkout"); return Results.Ok("⬅️ Old checkout"); });
Or gate an endpoint/page
[FeatureGate("NewCheckout")] public class CheckoutController : Controller { }
🌩️ Pro move: Azure App Configuration
If you want centralized flags + refresh without redeploy, Azure App Configuration integrates directly (and supports feature filters + refresh intervals).
When to use (✅) vs when not to (❌)
✅ Use it for:
- gradual rollouts (percentage / targeting)
- “dark launches”
- A/B experiments
- emergency kill switches
- decoupling deploy from release
❌ Avoid it for:
- permanent business rules (“VIPs always…”)
- long-lived flags that never get removed
- security boundaries (flags reduce exposure, but don’t replace authorization)
Best practices (the stuff that saves you later)
- Name flags like products, not tech (
Checkout.NewFlow,Billing.TaxesV2) - Set an owner + removal date
- Test both paths
- Delete dead flags (flag graveyards are real)