Desvincular deploy e release é fundamental para a gestão ágil dos ambientes produtivos. De maneira ideal, processos de deploy devem acontecer de maneira contínua e automática. Entretanto, a disponibilização de features deve ocorrer conforme a estratégia de gestão de produtos das organizações.
Veja também
Uma prática comum para alcançar este objetivo é sinalizar novas features, no código, com feature toggles ou feature flags, que podem ser “ligadas” ou “desligadas” por configuração, permitindo, assim, que novos pacotes sejam instalados no ambiente produtivo (deploy) sem, necessariamente, disponibilizar as novas funcionalidades (release).
Em Asp.NET core, feature flags podem ser facilmente acrescentadas aos projetos pela utilização do pacote nuget Microsoft.FeatureManagement.AspNetCore
.
dotnet add package Microsoft.FeatureManagement.AspNetCore --version 2.0.0
Trata-se de um pacote de fácil configuração.
public void ConfigureServices(IServiceCollection services) { // .. services.AddControllersWithViews(); // .. }
Com ele devidamente configurado, basta sinalizar as features que serão controladas diretamente em appsettings.json
, variáveis de ambiente ou, ainda, arquivos de configuração no Azure.
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "FeatureManagement": { "Privacy": true } }
O acesso a configuração das features no código pode ser feito, além do acesso programático, realizado pela injeção de dependência para IFeatureManager
, pela utilização de atributos.
using System.Diagnostics; using Microsoft.AspNetCore.Mvc; using Microsoft.FeatureManagement.Mvc; using SampleWebWithFeatures.Models; namespace SampleWebWithFeatures.Controllers { public class HomeController : Controller { public HomeController() {} public IActionResult Index() => View(); [FeatureGate("Privacy")] public IActionResult Privacy() => View(); [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } } }
Para as Views, é possível adicionar taghelpers (via @addTagHelper *, Microsoft.FeatureManagement.AspNetCore
) para ajudar a controlar o que é renderizado e o que não é.
<feature name="Privacy"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </li> </feature>
Em termos práticos, as maiores dificuldades estão relacionadas a gestão. Afinal, como podemos constatar, as restrições técnicas são mínimas.
No podcast da lambda3 (Microserviços 5) vocês tiveram diversas discussões para o feature toogle. Uma dúvida que eu tenho, é em relação ao comportamento de uma feature que já existe no projeto, exemplo simples: Tenho um cadastro de usuário que ao final da rotina, é ser disparado um e-mail, porém, na nova feature meu cliente quer que eu adicione um disparo de SMS além do disparo de e-mail existente. Esse controle seria um método v2 na rota da API?
Olá Henrique, acredito que as vezes, para introduzir uma nova feature de forma correta (usando feature toggle) é preciso refatorar o código existente segindo os princípios SOLID. Principalmente o Open-closed Principle, onde uma classe deve ser aberta para extensão e fechada para modificação. Nesse caso, você talvez precise refatorar o código existente para permitir adicionar e remover diferentes tipos de notificação (SMS, e-mail, bots) de forma que o restante do código não se importe qual a forma de notificação está sendo utilizada. Algo bem plug-and-play. Fazendo isso, você pode ativar ou desativar as diferentes formas de notificação usando feature toggles, e o seu código estará preparado para novas features (ie. novas formas de notificação). Desenvolver a aplicação pensando em feature toggles desde o início torna o código mais limpo e fácil de manter.
Olá Elemar, obrigado pelo post, ficou bem explicado. Fiquei curioso para saber como funciona através de variáveis de ambiente ou arquivo no Azure, como você mencionou. Depois vou dar uma olhada com mais calma na documentação. Mais uma vez, obrigado e abraços!