December 23 2025
This issue is made possible thanks to JetBrains, who help keep this newsletter free for everyone. A huge shout-out to them for their support of our community. Let's thank them by entering the link below. Struggling with slow builds, tricky bugs, or hard-to-understand performance issues? dotUltimate fixes all of that. Itâs the all-in-one toolbox for serious .NET developers. đ Upgrade your .NET workflow.
How do you enable or disable features without redeploying the app?
If your first thought is âIâll just flip a value in appsettings.jsonâ - youâre not alone. But thatâs also where most Feature Flag implementations quietly fail.
In the last few days, I shared a short post about Feature Flags in .NET, and the comments were exciting.
They all circled the same confusion:
Do we really avoid redeployment? How does this work with multiple instances? Is appsettings.json enough? Do I still need to run a DevOps release?
Letâs clear this up - with real code that actually works.
Letâs be very explicit.
âWithout redeployingâ means:
â no build â no release pipeline â no app restart â no new container image â behavior changes while the app is running
If changing a feature flag requires you to click 'Deploy', then you havenât decoupled deployment from release - you've just moved the toggle.
Yes, you can define feature flags in appsettings.json.
{ "FeatureManagement": { "BetaFeature": true }}
But hereâs the problem:
But it does not work for: ⢠multiple instances ⢠Kubernetes ⢠Azure App Service ⢠real production traffic
To truly avoid redeployment, feature flags must live outside the application.
Feature Flags must be: ⢠centrally stored ⢠shared across instances ⢠read at runtime ⢠refreshable without a restart In .NET, this is exactly what Azure App Configuration + Feature Management gives us. Letâs build this properly.
These give us: ⢠Feature Flags API ⢠Azure App Configuration integration ⢠runtime refresh support
dotnet add package Microsoft.FeatureManagement.AspNetCoredotnet add package Microsoft.Azure.AppConfiguration.AspNetCore
In Azure Portal:
In appsettings.json:
{ "AzureAppConfig": { "ConnectionString": "<YOUR_CONNECTION_STRING>" }}
In real projects, this belongs in Key Vault or environment variables.
This is the part most examples skip or oversimplify.
using Microsoft.FeatureManagement;using Microsoft.Extensions.Configuration.AzureAppConfiguration;Â var builder = WebApplication.CreateBuilder(args);Â // 1. Connect to Azure App Configurationbuilder.Host.ConfigureAppConfiguration(config =>{ var settings = config.Build(); config.AddAzureAppConfiguration(options => { options .Connect(settings["AzureAppConfig:ConnectionString"]) // Register feature flags .UseFeatureFlags(featureOptions => { featureOptions.CacheExpirationInterval = TimeSpan.FromSeconds(10); }) // Register refresh with a sentinel key .ConfigureRefresh(refresh => { refresh .Register("FeatureFlags:Sentinel", true) .SetCacheExpiration( TimeSpan.FromSeconds(10)); }); });});Â // 2. Add Feature Managementbuilder.Services.AddFeatureManagement();Â // 3. Add Azure App Config refresh middlewarebuilder.Services.AddAzureAppConfiguration();Â var app = builder.Build();Â // Enable refresh middlewareapp.UseAzureAppConfiguration();Â app.MapGet("/", () => "Feature Flags Demo is running");Â // Feature-gated endpointapp.MapGet("/beta", async (IFeatureManager featureManager) =>{ if (await featureManager.IsEnabledAsync("BetaFeature")) { return Results.Ok("Beta feature is ENABLED"); }Â return Results.Ok("Beta feature is DISABLED");});Â app.Run();
In Azure App Configuration:
Create a key-value pair: ⢠Key: FeatureFlags:Sentinel ⢠Value: any string (e.g. timestamp)
Whenever you update this value: ⢠all feature flags refresh ⢠no restart ⢠no redeploy
Run the app and call GET /beta â â disabled Enable BetaFeature in the Azure Portal Wait ~10 seconds Call /beta again â đ enabled
No redeploy. No restart. No pipeline.
Azure App Configuration does cache values.
If you donât configure refresh: ⢠changes may take minutes ⢠developers think âit doesnât workâ
Thatâs why: ⢠CacheExpirationInterval ⢠sentinel keys ⢠refresh middleware
matter a lot.
This is where most âFeature Flags donât workâ stories come from.
This setup works perfectly with: ⢠multiple app instances ⢠load balancers ⢠Kubernetes ⢠App Service scaling Because: ⢠flags are centralized ⢠decision logic is deterministic ⢠instances are stateless The feature decision does not depend on the instance.
Azure App Configuration is great if youâre already on Azure.
Other solid options: ⢠LaunchDarkly - enterprise-grade ⢠Unleash - open-source & self-hosted ⢠Flagsmith - SaaS or self-hosted
The provider matters less than the runtime architecture.
Feature Flags are powerful - but dangerous if abused: ⢠flags that live for years ⢠nested if statements everywhere ⢠âtemporaryâ flags that never die Best practice: ⢠flags should have an owner ⢠flags should have a removal date ⢠flags should not replace versioning
Feature Flags are not about hiding code paths.
hey are about decoupling deployment from release.
If flipping a flag requires a redeploy, you didnât gain flexibility - you added complexity.
If you want a deeper dive, Iâve already written a full article on Feature Flags in .NET with Azure Feature Management here.
More real-world .NET architecture topics coming soon đ That's all from me for today.
Want to enforce clean code automatically? My Pragmatic .NET Code Rules course shows you how to set up analyzers, CI quality gates, and architecture tests - a production-ready system that keeps your codebase clean without manual reviews. Or grab the free Starter Kit to try it out.
Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests â the exact system I use in real projects. Join here.
Not sure yet? Grab the free Starter Kit â a drop-in setup with the essentials from Module 01.
Design Patterns that Deliver â Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.
Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.
Every Monday morning, I share 1 actionable tip on C#, .NET & Architecture that you can use right away. Join here.
Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Architecture & Best Practices.
Subscribe to the TheCodeMan.net and be among the 20,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.