Tutorial: Usar sinalizadores de recursos em um aplicativo ASP.NET Core

As bibliotecas de Gerenciamento de Recursos do .NET fornecem suporte idiomático para implementação de sinalizadores de recursos em um aplicativo .NET ou ASP.NET Core. Essas bibliotecas permitem que você adicione sinalizadores de recursos ao código de maneira declarativa, de modo que não precise escrever código para habilitar ou desabilitar recursos com instruções if.

As bibliotecas do Gerenciamento de Recursos também gerenciam os ciclos de vida dos sinalizadores de recursos nos bastidores. Por exemplo, as bibliotecas atualizam e armazenam em cache os estados do sinalizador ou garantem um estado de sinalizador imutável durante uma chamada de solicitação. Além disso, a biblioteca ASP.NET Core oferece integrações prontas para uso, incluindo ações do controlador MVC, exibições, rotas e middleware.

Para ver a documentação de referência da API de gerenciamento de recursos do ASP.NET Core, confira Namespace Microsoft.FeatureManagement.

Neste tutorial, você aprenderá a:

  • Adicionar sinalizadores de recursos aos componentes principais de seu aplicativo para controlar a disponibilidade de recursos.
  • Integre-os à Configuração de Aplicativos ao usá-la para gerenciar sinalizadores de recursos.

Pré-requisitos

O Início Rápido Adicionar sinalizadores de recurso a um aplicativo ASP.NET Core mostra um exemplo simples de como usar sinalizadores de recurso em um aplicativo ASP.NET Core. Este tutorial mostra opções de configuração adicionais e os recursos das bibliotecas de Gerenciamento de Recursos. Você pode usar o aplicativo de exemplo criado no início rápido para experimentar o código de exemplo mostrado neste tutorial.

Configurar o gerenciamento de recursos

Para acessar o gerenciador de recursos do .NET, seu aplicativo precisa ter referências ao pacote NuGet Microsoft.Azure.AppConfiguration.AspNetCore e Microsoft.FeatureManagement.AspNetCore.

O gerenciador de recursos do .NET é configurado no sistema nativo de configuração da estrutura. Como resultado, você pode definir as configurações do sinalizador de recursos do aplicativo usando qualquer fonte de configuração compatível com o .NET, incluindo o arquivo appsettings.json local ou variáveis de ambiente.

Por padrão, o gerenciador de recursos recupera a configuração do sinalizador de recursos da seção "FeatureManagement" dos dados de configuração do .NET. Para usar a localização de configuração padrão, chame o método AddFeatureManagement do IServiceCollection passado para o método ConfigureServices da classe Startup.

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement();

Você pode especificar que a configuração do gerenciamento de recursos deve ser recuperada de uma seção de configuração diferente chamando Configuration.GetSection e passando o nome da seção desejada. O seguinte exemplo instrui o gerenciador de recursos a fazer a leitura de outra seção chamada "MyFeatureFlags":

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement(Configuration.GetSection("MyFeatureFlags"));

Se usar filtros em seus sinalizadores de recursos, você deverá incluir o namespace Microsoft.FeatureManagement.FeatureFilters e adicionar uma chamada para AddFeatureFilter especificando o nome do tipo do filtro que deseja usar como o tipo genérico do método. Para saber mais sobre como usar filtros de recursos para habilitar e desabilitar dinamicamente a funcionalidade, confira Habilitar a distribuição em etapas de recursos para públicos-alvo.

O seguinte exemplo mostra como usar um filtro de recurso interno chamado PercentageFilter:

using Microsoft.FeatureManagement;

builder.Services.AddFeatureManagement()
    .AddFeatureFilter<PercentageFilter>();

Em vez de embutir os sinalizadores de recursos no código do aplicativo, recomendamos que você os mantenha fora do aplicativo e os gerencie separadamente. Isso permite que você modifique os estados do sinalizador a qualquer momento e que essas alterações entrem em vigor no aplicativo imediatamente. O serviço de Configuração de Aplicativos do Azure fornece uma interface do usuário do portal dedicada para gerenciar todos os seus sinalizadores de recursos. O serviço de Configuração de Aplicativos do Azure também fornece os sinalizadores de recursos ao aplicativo diretamente por meio das respectivas bibliotecas de clientes do .NET.

A maneira mais fácil de conectar seu aplicativo ASP.NET Core à Configuração de Aplicativos é por meio do provedor de configuração incluído o pacote NuGet Microsoft.Azure.AppConfiguration.AspNetCore. Depois de incluir uma referência ao pacote, siga estas etapas para usar este pacote NuGet.

  1. Abra o arquivo Program.cs e adicione o seguinte código.

    using Microsoft.Extensions.Configuration.AzureAppConfiguration;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Configuration.AddAzureAppConfiguration(options =>
        options.Connect(
            builder.Configuration["ConnectionStrings:AppConfig"])
            .UseFeatureFlags());
    
  2. Atualize as configurações de middleware e serviço para seu aplicativo usando o código a seguir.

    Dentro da classe program.cs, registre os serviços de Configuração de Aplicativos do Azure e o middleware nos objetos builder e app:

    builder.Services.AddAzureAppConfiguration();
    
    app.UseAzureAppConfiguration();
    

Em um cenário típico, você atualizará os valores do sinalizador de recurso periodicamente à medida que implantar e habilitar e recursos diferentes do aplicativo. Por padrão, os valores de sinalizador de recurso são armazenados em cache por um período de 30 segundos, de modo que uma operação de atualização disparada quando o middleware recebe uma solicitação não atualizará o valor até que o valor armazenado em cache expire. O código a seguir mostra como alterar a hora de expiração do cache ou o intervalo de sondagem para 5 minutos definindo o CacheExpirationInterval na chamada como UseFeatureFlags.

config.AddAzureAppConfiguration(options =>
    options.Connect(
        builder.Configuration["ConnectionStrings:AppConfig"])
            .UseFeatureFlags(featureFlagOptions => {
                featureFlagOptions.CacheExpirationInterval = TimeSpan.FromMinutes(5);
    }));

Declaração do sinalizador de recurso

Cada declaração de sinalizador de recurso tem duas partes: um nome e uma lista de um ou mais filtros que são usados para avaliar se o estado de um recurso é ativado (ou seja, quando seu valor é True). Um filtro define um critério para os casos em que um recurso deve ser ligado.

Quando um sinalizador de recursos tem vários filtros, a lista de filtro é percorrida na ordem até um dos filtros determinar que o recurso deve ser habilitado. Neste ponto, o sinalizador de recursos é ativado e os resultados restantes do filtro são ignorados. Se nenhum filtro indicar que o recurso deve ser habilitado, o sinalizador de recursos será desativado.

O gerenciador de recursos dá suporte ao appsettings.json como uma fonte de configuração para sinalizadores de recursos. O seguinte exemplo mostra como configurar os sinalizadores de recursos em um arquivo JSON:

{"FeatureManagement": {
        "FeatureA": true, // Feature flag set to on
        "FeatureB": false, // Feature flag set to off
        "FeatureC": {
            "EnabledFor": [
                {
                    "Name": "Percentage",
                    "Parameters": {
                        "Value": 50
                    }
                }
            ]
        }
    }
}

Por convenção, a seção FeatureManagement deste documento JSON é usada para as configurações de sinalizadores de recursos. O exemplo anterior mostra três sinalizadores de recursos com seus filtros definidos na propriedade EnabledFor:

  • FeatureA está ativado.
  • FeatureB está desativado.
  • FeatureC especifica um filtro chamado Percentage com uma propriedade Parameters. Percentage é um filtro configurável. Neste exemplo, Percentage especifica uma probabilidade de 50% de que o sinalizador FeatureC esteja ativado. Para ver um guia de instruções sobre como usar filtros de recursos, confira Usar filtros de recursos para habilitar sinalizadores de recursos condicionais.

Usar injeção de dependência para acessar o IFeatureManager

Para algumas operações, como verificar manualmente os valores dos sinalizadores de recursos, você precisa obter uma instância do IFeatureManager. No ASP.NET Core MVC, você pode acessar o gerenciador de recursos IFeatureManager por meio da injeção de dependência. No exemplo a seguir, um argumento do tipo IFeatureManager é adicionado à assinatura do construtor para um controlador. O runtime resolve automaticamente a referência e fornece uma implementação da interface ao chamar o construtor. Se você estiver usando um modelo de aplicativo no qual o controlador já tem um ou mais argumentos de injeção de dependência no construtor, como ILogger, poderá simplesmente adicionar IFeatureManager como um argumento adicional:

using Microsoft.FeatureManagement;

public class HomeController : Controller
{
    private readonly IFeatureManager _featureManager;

    public HomeController(ILogger<HomeController> logger, IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
}

Referências de sinalizadores de recursos

Defina sinalizadores de recurso como variáveis de cadeia de caracteres para fazer referência a eles no código:

public static class MyFeatureFlags
{
    public const string FeatureA = "FeatureA";
    public const string FeatureB = "FeatureB";
    public const string FeatureC = "FeatureC";
}

Verificações de sinalizadores de recursos

Um padrão comum do gerenciamento de recursos é verificar se um sinalizador de recursos está definido como ativado e, se estiver, executar uma seção de código. Por exemplo:

IFeatureManager featureManager;
...
if (await featureManager.IsEnabledAsync(MyFeatureFlags.FeatureA))
{
    // Run the following code
}

Ações do controlador

Com controladores MVC, você pode usar o atributo FeatureGate para controlar se uma classe de controlador inteira ou uma ação específica será habilitada. O seguinte controlador HomeController exige que FeatureA esteja ativado antes de executar qualquer ação contida pela classe do controlador:

using Microsoft.FeatureManagement.Mvc;

[FeatureGate(MyFeatureFlags.FeatureA)]
public class HomeController : Controller
{
    ...
}

A seguinte ação Index exige que FeatureA esteja ativado para ser executada:

using Microsoft.FeatureManagement.Mvc;

[FeatureGate(MyFeatureFlags.FeatureA)]
public IActionResult Index()
{
    return View();
}

Quando uma ação ou um controlador MVC está bloqueado devido ao sinalizador de recursos controlador estar desativado, uma interface IDisabledFeaturesHandler registrada é chamada. A interface IDisabledFeaturesHandler padrão retorna um código de status 404 para o cliente sem nenhum corpo de resposta.

Exibições do MVC

Abra _ViewImports.cshtml no diretório Views e adicione o auxiliar de marca do gerenciador de recursos:

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

Em exibições do MVC, você pode usar uma marca <feature> para renderizar o conteúdo com base em se um sinalizador de recursos está habilitado:

<feature name="FeatureA">
    <p>This can only be seen if 'FeatureA' is enabled.</p>
</feature>

Para exibir o conteúdo alternativo quando os requisitos não forem atendidos, é possível usar o atributo negate.

<feature name="FeatureA" negate="true">
    <p>This will be shown if 'FeatureA' is disabled.</p>
</feature>

A marcar do recurso <feature> também pode ser usada para mostrar o conteúdo se qualquer ou todos os recursos em uma lista estiverem habilitados.

<feature name="FeatureA, FeatureB" requirement="All">
    <p>This can only be seen if 'FeatureA' and 'FeatureB' are enabled.</p>
</feature>
<feature name="FeatureA, FeatureB" requirement="Any">
    <p>This can be seen if 'FeatureA', 'FeatureB', or both are enabled.</p>
</feature>

Filtros do MVC

Configure filtros do MVC de modo que eles sejam ativados com base no estado de um sinalizador de recursos. Essa funcionalidade é limitada a filtros que implementam IAsyncActionFilter. O exemplo a seguir adiciona um filtro do MVC chamado ThirdPartyActionFilter. Esse filtro só é disparado no pipeline do MVC se FeatureA está habilitado.

using Microsoft.FeatureManagement.FeatureFilters;

IConfiguration Configuration { get; set;}

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => {
        options.Filters.AddForFeature<ThirdPartyActionFilter>(MyFeatureFlags.FeatureA);
    });
}

Middleware

Você também pode usar sinalizadores de recursos para adicionar middleware e branches do aplicativo condicionalmente. O seguinte exemplo só insere um componente de middleware no pipeline de solicitação quando FeatureA está habilitado:

app.UseMiddlewareForFeature<ThirdPartyMiddleware>(MyFeatureFlags.FeatureA);

Este código cria a funcionalidade mais genérica para gerar um branch de todo o aplicativo com base em um sinalizador de recursos:

app.UseForFeature(featureName, appBuilder => {
    appBuilder.UseMiddleware<T>();
});

Próximas etapas

Neste tutorial, você aprendeu a implementar sinalizadores de recursos no aplicativo ASP.NET Core usando as bibliotecas Microsoft.FeatureManagement. Para obter mais informações sobre o suporte de gerenciamento de recursos no ASP.NET Core e na Configuração de Aplicativos, confira os seguintes recursos: