O que são feature flags e por que você precisa deles
\nImagine: você escreveu uma nova funcionalidade incrível — por exemplo, uma busca inteligente com autocompletar. Tudo foi testado, o código passou pela revisão. Mas você não tem 100% de certeza de que os usuários vão aceitá-la. Ou tem medo de que, sob carga, ela falhe. O que fazer?
\nAntes, a resposta era simples: "Implante em produção e reze". Hoje somos mais inteligentes. Usamos feature flags (feature flags, feature toggles) — um mecanismo que permite ativar e desativar funcionalidades em tempo real, sem recompilação e reimplantação.
\nNeste artigo no PythonLib, vamos abordar como implementar feature flags em projetos C# — desde a implementação mais simples até cenários avançados com teste A/B e lançamentos canary.
\n\nPor que feature flags são essenciais para o desenvolvedor C#
\nFeature flags C# resolvem três tarefas principais:
\n- \n
- Implantação segura: implante o código em produção, mesmo que a funcionalidade ainda não esteja pronta. Basta desativar a flag. \n
- Desativação instantânea: algo deu errado? Um clique no painel de administração — e a funcionalidade problemática desaparece. \n
- Gerenciamento flexível de funções: ative funcionalidades para usuários específicos, regiões ou por tempo. \n
E o melhor: para gerenciamento de funções no .NET, não é preciso reinventar a roda — existe a biblioteca pronta Microsoft.FeatureManagement.
A maneira mais simples: arquivo de configuração
\nVamos começar com a abordagem básica — através do appsettings.json. Isso é ideal para feature toggles .NET simples.
Passo 1. Adicionando as configurações
\n{\n "FeatureManagement": {\n "NewSearchEngine": true,\n "DarkMode": false,\n "BetaDashboard": true\n }\n}\n\nPasso 2. Registrando o serviço
\nNo Program.cs, adicione:
builder.Services.AddFeatureManagement();\n\nPasso 3. Usando no código
\npublic class SearchController\n{\n private readonly IFeatureManager _featureManager;\n\n public SearchController(IFeatureManager featureManager)\n {\n _featureManager = featureManager;\n }\n\n public async Task<IActionResult> Search(string query)\n {\n if (await _featureManager.IsEnabledAsync("NewSearchEngine"))\n {\n return View("NewSearch", await _newEngine.SearchAsync(query));\n }\n return View("LegacySearch", await _oldEngine.SearchAsync(query));\n }\n}\nPronto! Agora, para ativar a nova funcionalidade, basta alterar true para false no arquivo de configuração e reiniciar a aplicação. Mas queremos fazer isso sem reiniciar, certo?
Feature flags dinâmicos: alternância sem reinicialização
\nPara conditional features C# sem recarregar, usamos provedores de configuração que carregam as alterações. A melhor opção é banco de dados ou Redis.
\n\nCriando um provedor a partir do banco de dados
\npublic class DatabaseFeatureDefinitionProvider : IFeatureDefinitionProvider\n{\n private readonly AppDbContext _db;\n\n public DatabaseFeatureDefinitionProvider(AppDbContext db)\n {\n _db = db;\n }\n\n public async Task<FeatureDefinition> GetFeatureDefinitionAsync(string featureName)\n {\n var feature = await _db.FeatureFlags\n .FirstOrDefaultAsync(f => f.Name == featureName);\n \n return feature != null \n ? new FeatureDefinition { Name = feature.Name, EnabledFor = feature.EnabledFor }\n : null;\n }\n\n public IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync()\n {\n return _db.FeatureFlags\n .Select(f => new FeatureDefinition { Name = f.Name, EnabledFor = f.EnabledFor })\n .AsAsyncEnumerable();\n }\n}\n\nRegistrando:
\nbuilder.Services.AddFeatureManagement