Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A biblioteca de gerenciamento de recursos do .NET fornece uma maneira de desenvolver e expor a funcionalidade do aplicativo com base em sinalizadores de recursos. Quando um novo recurso é desenvolvido, muitos aplicativos têm requisitos especiais, como quando o recurso deve ser habilitado e em que condições. Esta biblioteca fornece uma maneira de definir essas relações. Ele também se integra com padrões de código .NET comuns para tornar possível a exposição desses recursos.
Os sinalizadores de recursos fornecem uma maneira para os aplicativos .NET e ASP.NET Core ativarem ou desativarem recursos dinamicamente. Você pode usar sinalizadores de recursos em casos de uso básicos, como instruções condicionais. Você também pode usar sinalizadores de recursos em cenários mais avançados, como a adição condicional de rotas ou filtros MVC (model–view–controller). Os sinalizadores de recursos são criados sobre o sistema de configuração do .NET Core. Qualquer provedor de configuração do .NET Core é capaz de atuar como a espinha dorsal para sinalizadores de recursos.
Aqui estão alguns dos benefícios de usar a biblioteca de gerenciamento de recursos .NET:
- Ele usa convenções comuns para o gerenciamento de recursos.
- Tem uma baixa barreira à entrada:
- É construído sobre a
IConfigurationinterface. - Ele suporta a configuração de flags de funcionalidades em arquivos JSON.
- É construído sobre a
- Ele fornece gerenciamento de tempo de vida do sinalizador de recurso.
- Os valores de configuração podem mudar em tempo real.
- Os sinalizadores de recursos podem ser consistentes em toda a solicitação.
- Ele abrange cenários básicos a complexos, oferecendo suporte para os seguintes recursos:
- Ativando e desativando recursos por meio de um arquivo de configuração declarativa
- Apresentando diferentes variantes de um recurso para diferentes usuários
- Avaliando dinamicamente o estado de um recurso com base em uma chamada para um servidor
- Fornece extensões de API para ASP.NET Core e o framework MVC nas seguintes áreas:
- Encaminhamento
- Filtros
- Atributos de ação
A biblioteca de gerenciamento de recursos .NET é de código aberto. Para obter mais informações, consulte o repositório GitHub FeatureManagement-Dotnet .
Marcadores de funcionalidade
Os sinalizadores de recursos podem ser ativados ou desativados. O estado de um sinalizador pode ser condicional usando filtros de recursos.
Filtros de funcionalidades
Os filtros de recursos definem um cenário para quando um recurso deve ser habilitado. Para avaliar o estado de um recurso, sua lista de filtros de feição é percorrida até que um dos filtros determine que o recurso está habilitado. Neste ponto, a travessia pelos filtros de recursos é interrompida. Se nenhum filtro de recurso indicar que o recurso deve ser habilitado, ele será considerado desativado.
Por exemplo, suponha que você crie um filtro de recursos do navegador Microsoft Edge. Se uma solicitação HTTP vier do Microsoft Edge, seu filtro de recursos ativará todos os recursos aos quais ele está conectado.
Configuração do sinalizador de funcionalidade
O sistema de configuração .NET Core é usado para determinar o estado dos sinalizadores de recursos. A base deste sistema é a IConfiguration interface. Qualquer provedor para IConfiguration pode ser usado como o provedor de estado de recurso para a biblioteca de sinalizadores de recursos. Este sistema suporta cenários que vão desde o ficheiro de configuração appsettings.json até à Configuração de Aplicações do Azure.
Declaração de sinalizador de recurso
A biblioteca de gestão de funcionalidades suporta o arquivo de configuração appsettings.json como uma fonte de sinalizador de funcionalidades porque é um provedor para sistema .NET Core IConfiguration . Os flags de funcionalidades são declarados usando o Microsoft Feature Management schema. Esse esquema é independente de linguagem na origem e é suportado em todas as bibliotecas de gerenciamento de recursos da Microsoft.
O código no exemplo a seguir declara sinalizadores de recurso em um arquivo JSON:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
// Define feature flags in a JSON file.
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": false
},
{
"id": "FeatureU",
"enabled": true,
"conditions": {}
},
{
"id": "FeatureV",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Sun, 01 Jun 2025 13:59:59 GMT",
"End": "Fri, 01 Aug 2025 00:00:00 GMT"
}
}
]
}
}
]
}
}
A feature_management seção do documento JSON é usada por convenção para carregar as configurações do sinalizador de recurso. Você deve listar objetos de sinalizadores de funcionalidade no feature_flags array nesta seção. Este código lista três flags de funcionalidades. Cada objeto de sinalizador de recurso tem uma id e uma enabled propriedade.
- O
idvalor é o nome que você usa para identificar e fazer referência ao sinalizador de recurso. - A
enabledpropriedade especifica o estado habilitado do sinalizador de recurso.
Uma funcionalidade está desativada se enabled corresponder a false. Se enabled for true, o estado do recurso depende da propriedade conditions. A conditions propriedade declara as condições que são usadas para habilitar dinamicamente o recurso.
- Se um sinalizador de recurso não tiver uma
conditionspropriedade, o recurso estará ativado. - Se uma flag de funcionalidade tiver uma
conditionspropriedade e as suas condições forem atendidas, a funcionalidade está ativada. - Se uma flag de funcionalidade tiver uma
conditionspropriedade e as suas condições não forem atendidas, a funcionalidade estará desativada.
Os filtros de recursos client_filters são definidos na matriz. No código anterior, o FeatureV sinalizador de recurso tem um filtro de recurso chamado Microsoft.TimeWindow. Este filtro é um exemplo de um filtro de recurso configurável. Neste código, este filtro tem uma parameters propriedade. Esta propriedade é usada para configurar o filtro. Nesse caso, os horários de início e término para que o recurso esteja ativo são configurados.
Avançado: O caractere de dois pontos (:) é proibido em nomes de flags de funcionalidades.
Tipo de requisito
Dentro da conditions propriedade, a requirement_type propriedade é usada para determinar se os filtros devem usar Any ou All lógica ao avaliar o estado de um recurso. Se requirement_type não for especificado, o valor padrão será Any. Os requirement_type valores resultam no seguinte comportamento:
-
Any: Apenas um filtro precisa ser avaliado comotruepara que o recurso seja habilitado. -
All: Todo filtro precisa ser avaliado comotruepara que o recurso seja habilitado.
Uma requirement_type de All altera a forma como os filtros são percorridos:
- Se nenhum filtro estiver listado, o recurso será desativado.
- Se os filtros estiverem listados, eles serão percorridos até que as condições de um deles especifiquem que o recurso deve ser desativado. Se nenhum filtro indicar que o recurso deve ser desativado, ele será considerado habilitado.
{
"id": "FeatureW",
"enabled": true,
"conditions": {
"requirement_type": "All",
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Sun, 01 Jun 2025 13:59:59 GMT",
"End": "Fri, 01 Aug 00:00:00 GMT"
}
},
{
"name": "Microsoft.Percentage",
"parameters": {
"Value": "50"
}
}
]
}
}
Neste exemplo, o FeatureW sinalizador de recurso tem um requirement_type valor de All. Como resultado, todos os seus filtros devem avaliar a true para que o recurso seja habilitado. Nesse caso, o recurso é habilitado para 50% dos usuários durante a janela de tempo especificada.
Lidando com várias fontes de configuração
A partir da v4.3.0, você pode optar pela mesclagem personalizada para sinalizadores de recursos do esquema da Microsoft (a feature_management seção ). Quando o mesmo ID de sinalizador de recurso aparece em várias fontes de configuração, uma instância da classe interna ConfigurationFeatureDefinitionProvider mescla essas definições de acordo com a ordem de registro do provedor de configuração. Se houver um conflito, a última definição de sinalizador de recurso será usada. Esse comportamento difere da mesclagem baseada em índice de matriz padrão no .NET.
O código a seguir permite a mesclagem da configuração do sinalizador de recurso personalizado por meio da injeção de dependência:
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile("appsettings.prod.json")
.Build();
services.AddSingleton(configuration);
services.AddFeatureManagement();
services.Configure<ConfigurationFeatureDefinitionProviderOptions>(o =>
{
o.CustomConfigurationMergingEnabled = true;
});
Você também pode habilitar a mesclagem personalizada ao construir uma instância de ConfigurationFeatureDefinitionProvider:
var featureManager = new FeatureManager(
new ConfigurationFeatureDefinitionProvider(
configuration,
new ConfigurationFeatureDefinitionProviderOptions
{
CustomConfigurationMergingEnabled = true
}));
Exemplo de comportamento:
// appsettings.json
{
"feature_management": {
"feature_flags": [
{ "id": "FeatureA", "enabled": true },
{ "id": "FeatureB", "enabled": false }
]
}
}
// appsettings.prod.json (added later in ConfigurationBuilder)
{
"feature_management": {
"feature_flags": [
{ "id": "FeatureB", "enabled": true }
]
}
}
Quando activas a mesclagem personalizada, FeatureA permanece habilitado e FeatureB é definido como habilitado, dado que é a última declaração que se aplica. Quando você usa a mesclagem padrão do .NET, onde a mesclagem personalizada está desabilitada, as matrizes são mescladas por índice. Essa abordagem pode produzir resultados inesperados se as fontes não se alinharem por posição.
Esquema de gerenciamento de recursos do .NET
Em versões anteriores da biblioteca de gerenciamento de recursos, o esquema primário era o esquema de gerenciamento de recursos .NET.
A partir da versão 4.0.0 da biblioteca, novos recursos, incluindo variantes e telemetria, não são suportados no esquema de gerenciamento de recursos do .NET.
Nota
Se a configuração do sinalizador de recurso incluir uma declaração que esteja listada nas seções feature_management e FeatureManagement, a da seção feature_management será adotada.
Consumo
Em uma implementação básica, o gerenciamento de recursos verifica se um sinalizador de recurso está habilitado. Em seguida, executa ações com base no resultado. Esta verificação é feita através do IsEnabledAsync método de IVariantFeatureManager.
…
IVariantFeatureManager featureManager;
…
if (await featureManager.IsEnabledAsync("FeatureX"))
{
// Do something.
}
Registo de serviço
O gerenciamento de recursos depende da injeção de dependência do .NET Core. Como mostra o código a seguir, você pode usar convenções padrão para registrar serviços de gerenciamento de recursos:
using Microsoft.FeatureManagement;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddFeatureManagement();
}
}
Por padrão, o gerenciador de funcionalidades recupera a configuração do sinalizador de recurso da seção feature_management ou FeatureManagement dos dados de configuração do .NET Core. Se nenhuma seção existir, a configuração será considerada vazia.
Nota
Você também pode especificar que a configuração do sinalizador de recurso deve ser recuperada de uma seção de configuração diferente passando a seção para AddFeatureManagement. O exemplo a seguir especifica que o gerenciador de recursos deve ler a partir de uma seção chamada MyFeatureFlags em vez disso:
services.AddFeatureManagement(configuration.GetSection("MyFeatureFlags"));
Injeção de dependência
Ao usar a biblioteca de gerenciamento de funcionalidades com MVC, pode obter o objeto que implementa IVariantFeatureManager usando injeção de dependência.
public class HomeController : Controller
{
private readonly IVariantFeatureManager _featureManager;
public HomeController(IVariantFeatureManager featureManager)
{
_featureManager = featureManager;
}
}
Serviços de gestão de funcionalidades com escopo limitado
O AddFeatureManagement método adiciona serviços de gerenciamento de recursos como singletons dentro de um aplicativo. Alguns cenários exigem que os serviços de gestão de funcionalidades sejam adicionados como serviços com escopo definido. Por exemplo, talvez queira usar filtros de funcionalidades que consomem serviços delimitados para informações de contexto. Neste caso, você deve usar o AddScopedFeatureManagement método. Esse método garante que os serviços de gerenciamento de recursos, incluindo filtros de recursos, sejam adicionados como serviços com escopo.
services.AddScopedFeatureManagement();
Integração ASP.NET Core
A biblioteca de gerenciamento de recursos fornece funcionalidade no ASP.NET Core e MVC para habilitar cenários comuns de sinalizador de recursos em aplicativos Web. Esses recursos estão disponíveis fazendo referência ao pacote NuGet Microsoft.FeatureManagement.AspNetCore .
Controladores e ações
Um controlador MVC e ações podem exigir que um determinado recurso, ou um de qualquer lista de recursos, seja habilitado para ser executado. Você pode cumprir esse requisito usando um FeatureGateAttribute objeto. A FeatureGateAttribute classe é definida no Microsoft.FeatureManagement.Mvc namespace.
[FeatureGate("FeatureX")]
public class HomeController : Controller
{
…
}
No exemplo anterior, a HomeController classe é fechada por FeatureX.
HomeController As ações só podem ser executadas se o FeatureX recurso estiver habilitado.
[FeatureGate("FeatureX")]
public IActionResult Index()
{
return View();
}
No exemplo anterior, a ação Index MVC pode ser executada apenas se a FeatureX funcionalidade estiver habilitada.
Gestão de ações desativada
Quando um controlador ou ação MVC é bloqueado porque nenhum dos recursos especificados por ele está habilitado, uma implementação registrada de é invocada IDisabledFeaturesHandler . Por padrão, um manipulador minimalista é registrado que retorna um erro HTTP 404. Você pode substituir esse manipulador usando IFeatureManagementBuilder ao registar flags de funcionalidades.
public interface IDisabledFeaturesHandler
{
Task HandleDisabledFeatures(IEnumerable<string> features, ActionExecutingContext context);
}
Vista
Nas exibições MVC, você pode usar <feature> tags para renderizar conteúdo condicionalmente. Você pode basear as condições de renderização em se um recurso está habilitado ou se uma variante específica de um recurso é atribuída. Para obter mais informações, consulte Variantes, mais adiante neste artigo.
<feature name="FeatureX">
<p>This content appears only when 'FeatureX' is enabled.</p>
</feature>
<feature name="FeatureX" variant="Alpha">
<p>This content appears only when variant 'Alpha' of 'FeatureX' is assigned.</p>
</feature>
Você também pode negar a avaliação auxiliar de tag se quiser exibir conteúdo quando um recurso ou conjunto de recursos estiver desativado. Se você especificar negate="true", como nos exemplos a seguir, o conteúdo será renderizado somente quando FeatureX estiver desabilitado.
<feature negate="true" name="FeatureX">
<p>This content appears only when 'FeatureX' is disabled.</p>
</feature>
<feature negate="true" name="FeatureX" variant="Alpha">
<p>This content appears only when variant 'Alpha' of 'FeatureX' isn't assigned.</p>
</feature>
Você pode usar a tag <feature> para fazer referência a várias funcionalidades. Para fazer isso, especifique uma lista separada por vírgulas de recursos no name atributo.
<feature name="FeatureX,FeatureY">
<p>This content appears only when 'FeatureX' and 'FeatureY' are enabled.</p>
</feature>
Por padrão, todos os recursos listados devem ser habilitados para que a tag de recurso seja renderizada. Você pode substituir esse comportamento adicionando o requirement atributo, como mostra o exemplo a seguir.
<feature name="FeatureX,FeatureY" requirement="Any">
<p>This content appears only when 'FeatureX,' 'FeatureY,' or both are enabled.</p>
</feature>
Você também pode usar a tag <feature> para fazer referência a multiplas variantes. Para fazer isso, use um valor de requirement de Any e especifique uma lista de variantes separadas por vírgulas no atributo variant.
<feature name="FeatureX" variant="Alpha,Beta" requirement="Any">
<p>This content appears only when variant 'Alpha' or 'Beta' of 'FeatureX' is assigned.</p>
</feature>
Nota
- Se você especificar uma variante, deverá especificar apenas um recurso.
- Se você especificar várias variantes e usar um
requirementvalor deAnd, um erro será gerado. Não é possível atribuir várias variantes.
A <feature> tag requer um auxiliar de tag para funcionar. Para usar a tag, adicione o auxiliar de tag de gerenciamento de recursos ao arquivo _ViewImports.cshtml .
@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
Filtros MVC
Você pode configurar filtros de ação MVC que você aplica condicionalmente com base no estado de um recurso. Para configurar esses filtros, registre-os de maneira sensível a funcionalidades. O pipeline de gestão de funcionalidades suporta filtros de ação MVC assíncronos que implementam a interface IAsyncActionFilter.
services.AddMvc(o =>
{
o.Filters.AddForFeature<SomeMvcFilter>("FeatureX");
});
O código anterior registra um filtro MVC chamado SomeMvcFilter. Esse filtro só é acionado dentro do pipeline MVC se FeatureX estiver habilitado.
Páginas Razor
As páginas MVC Razor podem exigir que um determinado recurso, ou um de qualquer lista de recursos, esteja habilitado para ser executado. Você pode adicionar esse requisito usando um FeatureGateAttribute objeto. A FeatureGateAttribute classe é definida no Microsoft.FeatureManagement.Mvc namespace.
[FeatureGate("FeatureX")]
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
O código anterior configura uma página do Razor que requer que FeatureX esteja ativada. Se o recurso não estiver habilitado, a página gerará um resultado HTTP 404 (NotFound).
Ao usar um FeatureGateAttribute objeto em páginas do Razor, você deve colocar FeatureGateAttribute no tipo de manipulador de página. Não é possível colocá-lo em métodos de manipulador individuais.
Construção de aplicações
Você pode usar a biblioteca de gerenciamento de recursos para adicionar ramificações de aplicativos e middleware que são executados condicionalmente com base no estado de um recurso.
app.UseMiddlewareForFeature<ThirdPartyMiddleware>("FeatureX");
No código anterior, o aplicativo adiciona um componente de middleware que aparece no pipeline de solicitação somente se o FeatureX recurso estiver habilitado. Se o recurso estiver habilitado ou desabilitado durante o tempo de execução, o pipeline de middleware poderá ser alterado dinamicamente.
Como mostra o código a seguir, essa funcionalidade se baseia no recurso mais genérico de ramificar todo o aplicativo com base em um recurso.
app.UseForFeature(featureName, appBuilder =>
{
appBuilder.UseMiddleware<T>();
});
Implementar um filtro de recursos
A criação de um filtro de recursos fornece uma maneira de habilitar recursos com base em critérios definidos por você. Para implementar um filtro de recursos, você deve implementar a IFeatureFilter interface.
IFeatureFilter tem um único método chamado EvaluateAsync. Quando um recurso especifica que pode ser habilitado para um filtro de recurso, o EvaluateAsync método é chamado. Se EvaluateAsync retornar true, o recurso deve ser ativado.
O código a seguir demonstra como adicionar um filtro de recurso personalizado chamado MyCriteriaFilter.
services.AddFeatureManagement()
.AddFeatureFilter<MyCriteriaFilter>();
Você pode registar um filtro de funcionalidade chamando AddFeatureFilter<T> na implementação de IFeatureManagementBuilder que AddFeatureManagement retorna. O filtro de recursos tem acesso aos serviços na coleção de serviços que você usa para adicionar sinalizadores de recursos. Você pode usar a injeção de dependência para recuperar esses serviços.
Nota
Quando você faz referência a filtros em configurações de sinalizador de recurso (por exemplo, appsettings.json), você deve omitir a Filter parte do nome do tipo. Para obter mais informações, consulte Atributo de alias de filtro, mais adiante neste artigo.
Filtros de recursos parametrizados
Alguns filtros de recursos exigem parâmetros para avaliar se um recurso deve ser ativado. Por exemplo, um filtro de recursos do navegador pode ativar um recurso para um determinado conjunto de navegadores. Talvez você queira ativar um recurso nos navegadores Microsoft Edge e Chrome, mas não no Firefox.
Para implementar esta filtragem, pode criar um filtro de funcionalidade para esperar parâmetros. Você especifica esses parâmetros na configuração do recurso. No código, você os acessa através do FeatureFilterEvaluationContext parâmetro de IFeatureFilter.EvaluateAsync.
public class FeatureFilterEvaluationContext
{
/// <summary>
/// The name of the feature being evaluated
/// </summary>
public string FeatureName { get; set; }
/// <summary>
/// The settings provided for the feature filter to use when evaluating whether the feature should be enabled
/// </summary>
public IConfiguration Parameters { get; set; }
}
A FeatureFilterEvaluationContext classe tem uma propriedade chamada Parameters. Os parâmetros dessa propriedade representam uma configuração bruta que o filtro de recursos pode usar ao avaliar se o recurso deve ser habilitado. No exemplo de filtro de recurso do navegador, o filtro pode usar a Parameters propriedade para extrair um conjunto de navegadores permitidos especificados para o recurso. O filtro pode então verificar se a solicitação é de um desses navegadores.
[FilterAlias("Browser")]
public class BrowserFilter : IFeatureFilter
{
…
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
{
BrowserFilterSettings settings = context.Parameters.Get<BrowserFilterSettings>() ?? new BrowserFilterSettings();
//
// Use the settings to check whether the request is from a browser in BrowserFilterSettings.AllowedBrowsers.
}
}
Atributo de Filtro de Alias
Quando se regista um filtro de funcionalidade para um sinalizador de funcionalidade, o alias utilizado na configuração é o nome do tipo de filtro de funcionalidade com o sufixo Filter, caso exista, removido. Por exemplo, você deve se referir a MyCriteriaFilter como MyCriteria em configuração.
{
"id": "MyFeature",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "MyCriteria"
}
]
}
}
Você pode substituir esse nome usando a FilterAliasAttribute classe. Para declarar um nome a ser usado na configuração para fazer referência a um filtro de feição dentro de um sinalizador de feição, você pode decorar o filtro de feição com esse atributo.
Filtros de funcionalidades ausentes
Suponha que você configure um recurso para ser habilitado para um filtro de recurso específico. Se o filtro de funcionalidade não estiver registrado, uma exceção será gerada quando a funcionalidade for avaliada. Como mostra o código a seguir, você pode desabilitar a exceção usando opções de gerenciamento de recursos.
services.Configure<FeatureManagementOptions>(options =>
{
options.IgnoreMissingFeatureFilters = true;
});
Usar HttpContext
Os filtros de recursos podem avaliar se um recurso deve ser habilitado com base nas propriedades de uma solicitação HTTP. Essa verificação é realizada inspecionando o contexto HTTP. Como mostra o código a seguir, um filtro de funcionalidade pode obter uma referência ao contexto HTTP usando a injeção de dependência para obter uma implementação de IHttpContextAccessor.
public class BrowserFilter : IFeatureFilter
{
private readonly IHttpContextAccessor _httpContextAccessor;
public BrowserFilter(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
}
Você deve adicionar a IHttpContextAccessor implementação ao contêiner de injeção de dependência na inicialização para que ele esteja disponível. Você pode usar o seguinte método para registrar a implementação nos IServiceCollection serviços.
public void ConfigureServices(IServiceCollection services)
{
…
services.AddHttpContextAccessor();
…
}
Avançado:IHttpContextAccessor e HttpContext não devem ser usados nos componentes Razor de aplicações Blazor do lado do servidor. A abordagem recomendada para passar contexto HTTP em aplicações Blazor é copiar os dados para um serviço de escopo. Para aplicativos Blazor, você deve usar AddScopedFeatureManagement para registrar serviços de gerenciamento de recursos. Para obter mais informações, consulte Serviços de gestão de funcionalidades com escopo, anteriormente neste artigo.
Fornecer um contexto para a avaliação de funcionalidades
Em aplicativos de console, não há contexto ambiente como HttpContext aquele que os filtros de recursos podem usar para verificar se um recurso deve estar ativado. Nesse caso, os aplicativos precisam fornecer um objeto que represente um contexto para o sistema de gerenciamento de recursos para uso por filtros de recursos. Você pode usar IVariantFeatureManager.IsEnabledAsync<TContext>(string featureName, TContext appContext) para fornecer esse contexto. Para avaliar o estado de uma funcionalidade, os filtros de funcionalidades podem usar o appContext objeto que se fornece ao gestor de funcionalidades.
MyAppContext context = new MyAppContext
{
AccountId = current.Id
};
if (await featureManager.IsEnabledAsync(feature, context))
{
…
}
Filtros de características contextuais
Filtros de recursos contextuais implementam a IContextualFeatureFilter<TContext> interface. Esses filtros de características especiais podem tirar proveito do contexto que é passado quando IVariantFeatureManager.IsEnabledAsync<TContext> é chamado. O TContext parâmetro type em IContextualFeatureFilter<TContext> descreve o tipo de contexto que o filtro pode manipular. Ao desenvolver um filtro de recurso contextual, você pode estabelecer os requisitos para usar o filtro especificando um tipo de contexto.
Como cada tipo é um descendente da Object classe, um filtro que implementa IContextualFeatureFilter<object> pode ser chamado para qualquer contexto fornecido. O código a seguir fornece um exemplo de um filtro de recurso contextual específico. Neste código, um recurso é habilitado se uma conta estiver em uma lista configurada de contas habilitadas.
public interface IAccountContext
{
string AccountId { get; set; }
}
[FilterAlias("AccountId")]
class AccountIdFilter : IContextualFeatureFilter<IAccountContext>
{
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext featureEvaluationContext, IAccountContext accountId)
{
//
// Evaluate whether the feature should be on by using the IAccountContext that's provided.
}
}
A AccountIdFilter classe requer um objeto que implementa IAccountContext a ser fornecido para ser capaz de avaliar o estado de um recurso. Quando utilizas este filtro de função, quem chama precisa em certificar-se de que o objeto passado implementa IAccountContext.
Nota
Apenas uma única interface de filtro de recurso pode ser implementada por um único tipo. Tentar adicionar um filtro de recurso que implementa mais do que uma única interface de filtro de recurso resulta em uma ArgumentException exceção.
Usar filtros contextuais e não contextuais com o mesmo alias
Filtros que implementam IFeatureFilter e IContextualFeatureFilter podem compartilhar o mesmo alias. Especificamente, você pode ter um alias de filtro compartilhado por zero ou uma IFeatureFilter implementações e zero ou NIContextualFeatureFilter<ContextType> implementações se houver no máximo um filtro aplicável para ContextType.
Para entender o processo de seleção de um filtro quando filtros contextuais e não contextuais de mesmo nome são registrados em um aplicativo, considere o exemplo a seguir.
Três filtros compartilham o SharedFilterName alias:
- Um filtro não contextual chamado
FilterA - Um filtro contextual chamado
FilterBque aceita umTypeBcontexto - Um filtro contextual chamado
FilterCque aceita umTypeCcontexto
Um flag de recurso chamado MyFeature usa o filtro de recurso SharedFilterName na sua configuração.
Se os três filtros estiverem registados:
- Quando chama
IsEnabledAsync("MyFeature"), o filtroFilterAé usado para avaliar o flag de funcionalidade. - Quando você liga
IsEnabledAsync("MyFeature", context):- Se o tipo de
contextforTypeB,FilterBé usado. - Se o tipo de
contextforTypeC,FilterCé usado. - Se o tipo de
contextforTypeF,FilterAé usado.
- Se o tipo de
Filtros de funcionalidades incorporadas
Existem alguns filtros de recursos que acompanham o Microsoft.FeatureManagement pacote: PercentageFilter, TimeWindowFilter, ContextualTargetingFilter, e TargetingFilter. Todos os filtros, exceto TargetingFilter são adicionados automaticamente quando você usa o método para registrar o AddFeatureManagement gerenciamento de recursos.
TargetingFilter é adicionado usando o WithTargeting método. Para obter mais informações, consulte Segmentação, mais adiante neste artigo.
Cada um dos filtros de recursos internos tem seus próprios parâmetros. As seções a seguir descrevem esses filtros de recursos e fornecem exemplos.
Microsoft.Percentagem
O Microsoft.Percentage filtro fornece uma maneira de habilitar um recurso com base em uma porcentagem definida.
{
"id": "EnhancedPipeline",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.Percentage",
"parameters": {
"Value": 50
}
}
]
}
}
Microsoft.TimeWindow
O Microsoft.TimeWindow filtro fornece uma maneira de habilitar um recurso com base em uma janela de tempo.
- Se você especificar apenas um
Endvalor, o recurso será considerado ativado até esse momento. - Se você especificar apenas um
Startvalor, o recurso será considerado ativado em todos os pontos após esse período.
{
"id": "EnhancedPipeline",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Sun, 01 Jun 2025 13:59:59 GMT",
"End": "Fri, 01 Aug 2025 00:00:00 GMT"
}
}
]
}
}
Você pode configurar o filtro para aplicar uma janela de tempo de forma recorrente. Esse recurso pode ser útil quando você precisa ativar um recurso durante um período de baixo ou alto tráfego de um dia ou determinados dias da semana. Para expandir uma janela de tempo individual para uma janela de tempo recorrente, use um Recurrence parâmetro para especificar uma regra de recorrência.
Nota
Para usar a recorrência, você deve especificar Start e End valores. Com a recorrência, a parte da data do valor de End não especifica uma data de término para manter o filtro ativo. Em vez disso, o filtro usa a data de término, relativa à data de início, para definir a duração da janela de tempo recorrente.
{
"id": "EnhancedPipeline",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Fri, 22 Mar 2024 20:00:00 GMT",
"End": "Sat, 23 Mar 2024 02:00:00 GMT",
"Recurrence": {
"Pattern": {
"Type": "Daily",
"Interval": 1
},
"Range": {
"Type": "NoEnd"
}
}
}
}
]
}
}
As Recurrence configurações são compostas por duas partes:
- As
Patternconfigurações especificam a frequência com que a janela de tempo se repete. - As
Rangeconfigurações especificam por quanto tempo o padrão de recorrência se repete.
Padrão de recorrência
Existem dois tipos possíveis de padrões de recorrência: Daily e Weekly. Por exemplo, uma janela de tempo pode repetir-se todos os dias, a cada três dias, a cada segunda-feira ou a cada duas sextas-feiras.
Dependendo do tipo, determinados campos das Pattern configurações são obrigatórios, opcionais ou ignorados.
DailyO padrão de recorrência diária faz com que a janela de tempo se repita com base em um número especificado de dias entre cada ocorrência.
Property Relevância Description TypeNecessário O tipo de padrão de recorrência. Deve ser definido como Daily.IntervalOpcional O número de dias entre cada ocorrência. O valor predefinido é 1.WeeklyO padrão de recorrência semanal faz com que a janela de tempo se repita no mesmo dia ou dias da semana. Mas você pode especificar o número de semanas entre cada conjunto de ocorrências.
Property Relevância Description TypeNecessário O tipo de padrão de recorrência. Deve ser definido como Weekly.DaysOfWeekNecessário Os dias da semana em que o evento ocorre. IntervalOpcional O número de semanas entre cada conjunto de ocorrências. O valor predefinido é 1.FirstDayOfWeekOpcional O dia a utilizar como primeiro dia da semana. O valor predefinido é Sunday.O exemplo a seguir repete a janela de tempo a cada duas segundas e terças-feiras:
"Pattern": { "Type": "Weekly", "Interval": 2, "DaysOfWeek": ["Monday", "Tuesday"] }
Nota
O Start valor deve ser uma primeira ocorrência válida que se encaixe no padrão de recorrência. Além disso, a duração da janela de tempo não pode ser maior do que a frequência com que ocorre. Por exemplo, uma janela de tempo de 25 horas não pode se repetir todos os dias.
Intervalo de recorrência
Existem três tipos possíveis de intervalo de recorrência: NoEnd, EndDate, e Numbered.
NoEndO
NoEndintervalo faz com que a recorrência ocorra indefinidamente.Property Relevância Description TypeNecessário O tipo de intervalo de recorrência. Deve ser definido como NoEnd.EndDateO
EndDateintervalo faz com que a janela de tempo ocorra em todos os dias que se ajustam ao padrão aplicável até a data final.Property Relevância Description TypeNecessário O tipo de intervalo de recorrência. Deve ser definido como EndDate.EndDateNecessário A data e a hora para parar de aplicar o padrão. Se a hora de início da última ocorrência for anterior à data final, a hora de término dessa ocorrência pode se estender além dela. No exemplo a seguir, a janela de tempo se repete todos os dias até a última ocorrência em 1º de abril de 2024.
"Start": "Fri, 22 Mar 2024 18:00:00 GMT", "End": "Fri, 22 Mar 2024 20:00:00 GMT", "Recurrence":{ "Pattern": { "Type": "Daily", "Interval": 1 }, "Range": { "Type": "EndDate", "EndDate": "Mon, 1 Apr 2024 20:00:00 GMT" } }NumberedO
Numberedintervalo determina que a janela de tempo ocorra um número definido de vezes.Property Relevância Description TypeNecessário O tipo de intervalo de recorrência. Deve ser definido como Numbered.NumberOfOccurrencesNecessário O número de ocorrências. No exemplo a seguir, a janela de tempo se repete na segunda e terça-feira para um total de três ocorrências, que acontecem nas seguintes datas:
- Segunda-feira, 1 de abril
- Terça-feira, 2 de abril
- Segunda-feira, 8 de abril
"Start": "Mon, 1 Apr 2024 18:00:00 GMT", "End": "Mon, 1 Apr 2024 20:00:00 GMT", "Recurrence":{ "Pattern": { "Type": "Weekly", "Interval": 1, "DaysOfWeek": ["Monday", "Tuesday"] }, "Range": { "Type": "Numbered", "NumberOfOccurrences": 3 } }
Para criar uma regra de recorrência, deve especificar tanto as configurações de Pattern como as configurações de Range. Qualquer tipo de padrão pode funcionar com qualquer tipo de intervalo.
Avançado: O deslocamento de fuso horário da Start propriedade é aplicado às configurações de recorrência.
Microsoft.Targeting
O Microsoft.Targeting filtro fornece uma maneira de habilitar um recurso para um público-alvo. Para obter uma explicação detalhada da segmentação, consulte Segmentação, mais adiante neste artigo.
Os parâmetros de filtro incluem um Audience objeto que descreve quem tem acesso ao recurso. Dentro do Audience objeto, você pode especificar usuários, grupos, usuários e grupos excluídos e uma porcentagem padrão da base de usuários.
Para cada objeto de grupo listado Groups na seção, você também deve especificar qual porcentagem dos membros do grupo deve ter acesso.
Para cada usuário, o recurso é avaliado da seguinte maneira:
Se o usuário for excluído, o recurso será desativado para o usuário. Você pode excluir o usuário da seguinte forma:
- Listar o nome deles sob
Usersna seçãoExclusion. - Na seção
Groups, listar o grupo ao qual eles pertencem sobExclusion.
- Listar o nome deles sob
Se o usuário não for excluído, o recurso será habilitado se qualquer uma das seguintes condições for atendida:
- O utilizador está listado na secção
Users. - O utilizador está incluído na percentagem de qualquer uma das implementações do grupo.
- O usuário cai na porcentagem de distribuição padrão.
- O utilizador está listado na secção
Se nenhum dos casos anteriores se aplicar, o recurso será desativado para o usuário. Por exemplo, se o usuário não estiver em uma porcentagem incluída, o recurso será desativado.
{
"id": "EnhancedPipeline",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.Targeting",
"parameters": {
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
},
{
"Name": "Ring1",
"RolloutPercentage": 50
}
],
"DefaultRolloutPercentage": 20,
"Exclusion": {
"Users": [
"Ross"
],
"Groups": [
"Ring2"
]
}
}
}
}
]
}
}
Namespaces de alias de filtro de funcionalidade
Todos os aliases de filtro de recursos internos estão no namespace do filtro de Microsoft recursos. Estar nesse namespace evita conflitos com outros filtros de recursos que compartilham o mesmo alias. Os segmentos de um namespace de filtro de funcionalidades são separados pelo caractere .. Você pode fazer referência a um filtro de funcionalidades por seu alias totalmente qualificado, como Microsoft.Percentage. Ou você pode fazer referência ao último segmento, como Percentage.
Seleção do destino
A segmentação é uma estratégia de gerenciamento de recursos que você pode usar para implantar progressivamente novos recursos em sua base de usuários. A estratégia baseia-se no conceito de segmentação de um conjunto de utilizadores conhecido como público-alvo. Um público é composto por usuários específicos, grupos, usuários e grupos excluídos e uma porcentagem designada de toda a base de usuários. Os grupos que estão incluídos na audiência podem ser divididos em porcentagens de seus membros totais.
As etapas a seguir demonstram um exemplo de uma distribuição progressiva para um novo recurso chamado Beta:
- Os usuários individuais Jeff e Alicia têm acesso ao recurso Beta.
- Outro usuário, Mark, pede para aceitar e é incluído.
- Vinte por cento dos usuários no grupo Ring1 estão incluídos no recurso Beta.
- O número de usuários do Ring1 incluídos é aumentado para 100%.
- Cinco por cento da base de utilizadores está incluída na funcionalidade Beta.
- A porcentagem de lançamento é aumentada para 100% para implementar completamente o recurso.
A biblioteca oferece suporte a essa estratégia para implantar um recurso por meio do filtro de recursos Microsoft.Targeting interno.
Segmentação numa aplicação web
Para um exemplo de uma aplicação Web que utiliza o filtro de funcionalidade de segmentação, consulte o projeto de exemploFeatureFlagDemo.
Para começar a usar TargetingFilter em um aplicativo, você deve adicioná-lo à coleção de serviços do aplicativo como qualquer outro filtro de recurso. Ao contrário de outros filtros internos, TargetingFilter depende de outro serviço a ser adicionado à coleção de serviços do aplicativo. Esse serviço é uma ITargetingContextAccessor implementação.
A Microsoft.FeatureManagement.AspNetCore biblioteca fornece uma implementação padrão do ITargetingContextAccessor que extrai informações de direcionamento do valor do HttpContext de uma solicitação. Você pode usar o acessador de contexto de segmentação padrão ao configurar a segmentação usando a sobrecarga não genérica WithTargeting em IFeatureManagementBuilder.
Para registar o acessor de contexto de segmentação padrão e TargetingFilter, chama-se WithTargeting em IFeatureManagementBuilder.
services.AddFeatureManagement()
.WithTargeting();
Você também pode registrar uma implementação personalizada para e ITargetingContextAccessor ligando TargetingFilterpara WithTargeting<T> . O código a seguir configura o gerenciamento de recursos em um aplicativo Web para usar TargetingFilter com uma implementação chamada ITargetingContextAccessorExampleTargetingContextAccessor.
services.AddFeatureManagement()
.WithTargeting<ExampleTargetingContextAccessor>();
ITargetingContextAccessor
Para usar TargetingFilter em um aplicativo Web, é necessária uma implementação de ITargetingContextAccessor . O raciocínio por trás desse requisito é que informações contextuais, como informações sobre o usuário, são necessárias para direcionar avaliações. Essas informações são armazenadas em instâncias da TargetingContext classe. Diferentes aplicativos extraem essas informações de locais diferentes, como o contexto HTTP de uma solicitação ou um banco de dados.
Para obter um exemplo que extrai informações de contexto de destino do contexto HTTP de um aplicativo, consulte DefaultHttpTargetingContextAccessor no Microsoft.FeatureManagement.AspNetCore pacote. Extrai as seguintes informações:
- Informações de segmentação da
HttpContext.Userpropriedade -
UserIdinformações doIdentity.Namecampo -
Groupsinformações de sinistros do tipoRole
Esta implementação baseia-se na utilização de IHttpContextAccessor. Para mais informações sobre IHttpContextAccessor, consulte HttpContext, nesta secção do artigo.
Segmentação em um aplicativo de console
O filtro de segmentação depende de um contexto de segmentação para avaliar se um recurso deve ser ativado. Esse contexto de segmentação contém informações como o usuário que está sendo avaliado e os grupos aos quais o usuário pertence. Em aplicativos de console, normalmente não há contexto ambiente disponível para passar essas informações para o filtro de segmentação. Como resultado, deves passá-lo diretamente quando chamares FeatureManager.IsEnabledAsync. Esse tipo de contexto é suportado pelo uso do ContextualTargetingFilter. Os aplicativos que precisam enviar o contexto de segmentação para o gerenciador de recursos devem usar ContextualTargetingFilter em vez de TargetingFilter.
Como ContextualTargetingFilter implementa IContextualTargetingFilter<ITargetingContext>, você deve passar uma implementação de ITargetingContext para IVariantFeatureManager.IsEnabledAsync para que ele possa avaliar e ativar um recurso.
IVariantFeatureManager fm;
…
// The userId and groups variables are defined earlier in the application.
TargetingContext targetingContext = new TargetingContext
{
UserId = userId,
Groups = groups
};
await fm.IsEnabledAsync(featureName, targetingContext);
ContextualTargetingFilter usa o alias Microsoft.Targetingdo filtro de recursos , portanto, a configuração desse filtro é consistente com as informações em Microsoft.Targeting, anteriormente neste artigo.
Para obter um exemplo que usa ContextualTargetingFilter em um aplicativo de console, consulte o projeto de exemplo TargetingConsoleApp .
Direcionar as opções de avaliação
Estão disponíveis opções para personalizar a forma como a avaliação de segmentação é realizada em todos os recursos. Você pode configurar essas opções ao configurar o gerenciamento de recursos.
services.Configure<TargetingEvaluationOptions>(options =>
{
options.IgnoreCase = true;
});
Segmentação da exclusão
Ao definir uma audiência, você pode excluir usuários e grupos da audiência. Essa funcionalidade é útil quando você implementa um recurso para um grupo de usuários, mas precisa excluir alguns usuários ou grupos da distribuição. Para especificar utilizadores e grupos que deseja excluir, use a propriedade Exclusion de um grupo-alvo.
"Audience": {
"Users": [
"Jeff",
"Alicia"
],
"Groups": [
{
"Name": "Ring0",
"RolloutPercentage": 100
}
],
"DefaultRolloutPercentage": 0,
"Exclusion": {
"Users": [
"Mark"
]
}
}
O código anterior habilita um recurso para usuários chamados Jeff e Alicia. O recurso também está habilitado para usuários no grupo chamado Ring0. No entanto, o recurso está desabilitado para o usuário chamado Mark, mesmo que esse usuário esteja no Ring0 grupo. As exclusões têm prioridade sobre o restante do filtro de segmentação.
Variantes
Às vezes, quando você adiciona um novo recurso a um aplicativo, o recurso tem várias opções de design propostas. Os testes A/B fornecem uma solução comum para decidir sobre um projeto. O teste A/B envolve fornecer uma versão diferente do recurso para diferentes segmentos da base de usuários e, em seguida, escolher uma versão com base na interação do usuário. Na biblioteca de gerenciamento de recursos do .NET, você pode implementar testes A/B usando variantes para representar várias configurações de um recurso.
As variantes fornecem uma maneira para que um flag de funcionalidade se torne mais do que um sinalizador básico de ativar/desativar. Uma variante representa um valor de um sinalizador de recurso que pode ser uma cadeia de caracteres, um número, um booleano ou até mesmo um objeto de configuração. Um sinalizador de recurso que declara variantes deve definir as circunstâncias em que cada variante deve ser usada. Para obter mais informações, consulte Alocar variantes, mais adiante neste artigo.
public class Variant
{
/// <summary>
/// The name of the variant
/// </summary>
public string Name { get; set; }
/// <summary>
/// The configuration of the variant
/// </summary>
public IConfigurationSection Configuration { get; set; }
}
Recuperar variantes
Para cada funcionalidade, pode recuperar uma variante usando o método GetVariantAsync da interface IVariantFeatureManager.
…
IVariantFeatureManager featureManager;
…
Variant variant = await featureManager.GetVariantAsync("MyVariantFeatureFlag", CancellationToken.None);
IConfigurationSection variantConfiguration = variant.Configuration;
// Do something with the resulting variant and its configuration.
Depois de recuperar uma variante, pode usar a configuração diretamente como uma implementação de IConfigurationSection a partir da propriedade Configuration da variante. Outra opção é vincular a configuração a um objeto usando o padrão de vinculação de configuração do .NET.
IConfigurationSection variantConfiguration = variant.Configuration;
MyFeatureSettings settings = new MyFeatureSettings();
variantConfiguration.Bind(settings);
A variante que é retornada depende do usuário que está sendo avaliado. Você pode obter informações sobre o usuário de uma instância do TargetingContext. Você pode passar neste contexto quando você chama GetVariantAsync. Ou pode ser recuperado automaticamente a partir de uma implementação de ITargetingContextAccessor se estiver registado.
Declaração de sinalizador de funcionalidade variante
Em comparação com os sinalizadores de recursos padrão, os sinalizadores de recursos variantes têm duas propriedades extras: variants e allocation. A variants propriedade é uma matriz que contém as variantes definidas para o recurso. A allocation propriedade define como essas variantes devem ser alocadas para o recurso. Assim como declarar sinalizadores de recurso padrão, você pode configurar sinalizadores de recurso variante em um arquivo JSON. O código a seguir é um exemplo de um sinalizador de recurso variante:
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"default_when_enabled": "Small",
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
]
},
"variants": [
{
"name": "Big"
},
{
"name": "Small"
}
]
}
]
}
}
Definir variantes
Cada variante tem duas propriedades: um nome e uma configuração. O nome é usado para se referir a uma variante específica, e a configuração é o valor dessa variante. Você pode usar a configuration_value propriedade para especificar a configuração. A configuration_value propriedade é uma configuração embutida que pode ser uma cadeia de caracteres, número, booleano ou objeto de configuração. Se você não configurar a configuration_value propriedade, a propriedade da variante Configuration retornada será null.
Para especificar todas as variantes possíveis para um recurso, liste-as na propriedade variants.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"variants": [
{
"name": "Big",
"configuration_value": {
"Size": 500
}
},
{
"name": "Small",
"configuration_value": {
"Size": 300
}
}
]
}
]
}
}
Alocar variantes
Para alocar as variantes de um recurso, use a allocation propriedade do recurso.
"allocation": {
"default_when_enabled": "Small",
"default_when_disabled": "Small",
"user": [
{
"variant": "Big",
"users": [
"Marsha"
]
}
],
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
],
"percentile": [
{
"variant": "Big",
"from": 0,
"to": 10
}
],
"seed": "13973240"
},
"variants": [
{
"name": "Big",
"configuration_value": "500px"
},
{
"name": "Small",
"configuration_value": "300px"
}
]
A allocation configuração tem as seguintes propriedades:
| Property | Description |
|---|---|
default_when_disabled |
A variante a ser usada quando uma variante é solicitada enquanto o recurso é considerado desativado. |
default_when_enabled |
A variante a ser usada quando uma variante é solicitada enquanto o recurso é considerado habilitado e nenhuma outra variante é atribuída ao usuário. |
user |
Uma variante e uma lista de usuários aos quais atribuir a variante. |
group |
Uma variante e uma lista de grupos. A variante é atribuída se o usuário atual estiver em pelo menos um dos grupos. |
percentile |
Uma variante e um intervalo percentual no qual a porcentagem calculada do usuário deve se encaixar para que a variante seja atribuída. |
seed |
O valor sobre o qual os cálculos percentuais para percentile se baseiam. O cálculo de porcentagem para um usuário específico é o mesmo em todos os recursos se o mesmo seed valor for usado. Se nenhum seed valor for especificado, uma semente padrão será criada com base no nome do recurso. |
Se um recurso não estiver habilitado, o gerenciador de recursos atribuirá a variante especificada para default_when_disabled ao usuário atual. No exemplo anterior, este recurso é chamado Small.
Se o recurso estiver ativado, o gestor de recursos verificará as alocações user, group e percentile nessa ordem para atribuir uma variante. No exemplo anterior, a variante especificada, Big, é atribuída ao usuário nos seguintes casos:
- O usuário que está sendo avaliado é chamado
Marsha. - O utilizador está no grupo
Ring1. - O usuário passa a cair entre o percentil zero e décimo.
Se nenhuma dessas alocações corresponder, a default_when_enabled variante será atribuída ao usuário. No exemplo, essa variante é Small.
A lógica de alocação é semelhante à lógica usada para o filtro de recursos Microsoft.Targeting . Mas há alguns parâmetros que estão presentes na segmentação que não estão na alocação, e vice-versa. Os resultados da segmentação e da alocação não estão relacionados.
Nota
Para alocar variantes de recurso, precisas registar-te ITargetingContextAccessor chamando o método WithTargeting<T>.
Sobrescrever o estado habilitado utilizando uma variante
Você pode usar variantes para substituir o estado ativado de um sinalizador de recurso. Ao aproveitar esta funcionalidade, o utilizador pode estender a avaliação de uma feature flag. Durante a chamada para IsEnabledAsync em um sinalizador com variantes, o gerenciador de recursos verifica se a variante atribuída ao usuário atual está configurada para substituir o resultado.
Você pode implementar a sobrescrição através da propriedade opcional variant status_override. Esta propriedade pode ter os seguintes valores:
-
None: A variante não afeta se o sinalizador é considerado ativado ou desativado.Noneé o valor padrão. -
Enabled: Quando a variante é escolhida, o sinalizador de recurso é avaliado como habilitado. -
Disabled: Quando a variante é escolhida, o sinalizador de recurso é avaliado como desativado.
Não é possível substituir um recurso por um enabled estado de false.
Se você usar um sinalizador de recurso com variantes binárias, a status_override propriedade pode ser útil. Você pode continuar a usar APIs como IsEnabledAsync e FeatureGateAttribute em seu aplicativo. Mas pode beneficiar-se também dos recursos que vêm com as variantes, como a alocação de percentis e a utilização de um valor semente para os cálculos percentuais.
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"percentile": [
{
"variant": "On",
"from": 10,
"to": 20
}
],
"default_when_enabled": "Off",
"seed": "Enhanced-Feature-Group"
},
"variants": [
{
"name": "On"
},
{
"name": "Off",
"status_override": "Disabled"
}
]
}
No exemplo anterior, o recurso está sempre habilitado. Se o usuário atual estiver no intervalo de percentis calculado de 10 a 20, a On variante será retornada. Caso contrário, a Off variante será retornada e, como o status_override valor é Disabled, o recurso será considerado desativado.
Variantes na injeção de dependência
Você pode usar sinalizadores de recursos variantes juntamente com a injeção de dependência para expor diferentes implementações de um serviço para usuários diferentes. A IVariantServiceProvider<TService> interface fornece uma maneira de realizar essa combinação.
IVariantServiceProvider<IAlgorithm> algorithmServiceProvider;
...
IAlgorithm forecastAlgorithm = await algorithmServiceProvider.GetServiceAsync(cancellationToken);
No código anterior, a IVariantServiceProvider<IAlgorithm> implementação recupera uma implementação de IAlgorithm do contentor de injeção de dependências. A implementação escolhida depende de:
- O sinalizador de recurso com o qual o
IAlgorithmserviço está registrado. - A variante alocada para esse recurso.
A IVariantServiceProvider<T> implementação é disponibilizada para o aplicativo chamando IFeatureManagementBuilder.WithVariantService<T>(string featureName), como mostra o exemplo a seguir. A chamada neste código torna IVariantServiceProvider<IAlgorithm> disponível na coleção de serviços.
services.AddFeatureManagement()
.WithVariantService<IAlgorithm>("ForecastAlgorithm");
Você deve adicionar cada implementação de IAlgorithm separadamente por meio de um método como services.AddSingleton<IAlgorithm, SomeImplementation>(). A implementação de IAlgorithm que IVariantServiceProvider utiliza depende do sinalizador de característica variante ForecastAlgorithm. Se nenhuma implementação de IAlgorithm for adicionada à coleção de serviços, o IVariantServiceProvider<IAlgorithm>.GetServiceAsync() retornará uma tarefa com resultado null.
{
// The example variant feature flag
"id": "ForecastAlgorithm",
"enabled": true,
"variants": [
{
"Name": "AlgorithmBeta"
},
...
]
}
Atributo de alias de variante de serviço
O provedor de serviços de variante usa os nomes de tipo das implementações para corresponder à variante alocada. Se um serviço de variante for decorado com VariantServiceAliasAttribute, o nome declarado neste atributo deve ser usado na configuração para fazer referência a esse serviço de variante.
[VariantServiceAlias("Beta")]
public class AlgorithmBeta : IAlgorithm
{
...
}
Telemetria
Quando você implanta uma alteração de sinalizador de recurso, geralmente é importante analisar seu efeito em um aplicativo. Por exemplo, aqui estão algumas perguntas que podem surgir:
- Os sinalizadores estão ativados e desativados conforme o esperado?
- Os usuários-alvo estão tendo acesso a um determinado recurso conforme o esperado?
- Qual variante um usuário específico está vendo?
A emissão e análise de eventos de avaliação de flags de funcionalidade podem ajudá-lo a responder a estes tipos de perguntas. A biblioteca de gerenciamento de recursos .NET usa a API para produzir telemetria de rastreamento durante a System.Diagnostics.Activity avaliação do sinalizador de recurso.
Ativar telemetria
Por padrão, os sinalizadores de recursos não têm telemetria emitida. Para publicar telemetria para um sinalizador de recurso específico, o sinalizador deve declarar que está ativado para emissão de telemetria.
Para funcionalidades definidas em appsettings.json, pode ativar a telemetria usando a propriedade telemetry.
{
"feature_management": {
"feature_flags": [
{
"id": "MyFeatureFlag",
"enabled": true,
"telemetry": {
"enabled": true
}
}
]
}
}
O código anterior de um arquivo appsettings.json define um sinalizador de recurso chamado MyFeatureFlag que está habilitado para telemetria. O estado de telemetria telemetry é indicado pelo objeto que define enabled como true. O valor da enabled propriedade deve ser true publicar telemetria para o sinalizador.
A telemetry seção de um sinalizador de recurso tem as seguintes propriedades:
| Property | Description |
|---|---|
enabled |
Um valor booleano que especifica se a telemetria deve ser publicada para o sinalizador de funcionalidades. |
metadata |
Uma coleção de pares chave-valor, modelada como um dicionário, que pode-se usar para anexar metadados personalizados sobre o flag de funcionalidade a eventos de avaliação. |
Nota
Quando utiliza o fornecedor de configuração .NET com o Azure App Configuration, são adicionados metadados adicionais de telemetria para avaliar flags de funcionalidades quando a telemetria está ativada.
Publicação de telemetria personalizada
O gerenciador de recursos tem sua própria ActivitySource instância chamada Microsoft.FeatureManagement. Se a telemetria estiver habilitada para um sinalizador de recurso:
- Quando uma avaliação de sinalizador de funcionalidade é iniciada, o gestor de funcionalidades inicia uma instância do
Activity. - Quando uma avaliação de sinalizador de recurso é concluída, o gerenciador de recursos adiciona uma
ActivityEventinstância nomeadaFeatureFlagà atividade atual.
O FeatureFlag evento tem tags que incluem as informações sobre a avaliação do sinalizador de recurso. As tags usam os campos definidos no esquema FeatureEvaluationEvent .
Nota
Todos os pares chave-valor especificados na telemetry.metadata propriedade do sinalizador de recurso também são incluídos nas tags.
Para habilitar a publicação de telemetria personalizada, pode criar uma instância de ActivityListener e ouvir a fonte de atividade Microsoft.FeatureManagement. O código a seguir mostra como ouvir a fonte de atividade de gestão de funcionalidades e adicionar uma função de retorno quando uma funcionalidade é avaliada.
ActivitySource.AddActivityListener(new ActivityListener()
{
ShouldListenTo = (activitySource) => activitySource.Name == "Microsoft.FeatureManagement",
Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData,
ActivityStopped = (activity) =>
{
ActivityEvent? evaluationEvent = activity.Events.FirstOrDefault((activityEvent) => activityEvent.Name == "FeatureFlag");
if (evaluationEvent.HasValue && evaluationEvent.Value.Tags.Any())
{
// Do something.
}
}
});
Para obter mais informações, consulte Coletar um rastreamento distribuído.
Telemetria do Application Insights
O Microsoft.FeatureManagement.Telemetry.ApplicationInsights pacote fornece um editor de telemetria interno que envia dados de avaliação do sinalizador de recursos para o Application Insights. O pacote Microsoft.FeatureManagement.Telemetry.ApplicationInsights também fornece um inicializador de telemetria que automaticamente marca todos os eventos com TargetingId, permitindo que os eventos sejam vinculados às avaliações de sinalizadores. Para aproveitar essa funcionalidade, adicione uma referência ao pacote e registre a telemetria do Application Insights. O código a seguir fornece um exemplo:
builder.services
.AddFeatureManagement()
.AddApplicationInsightsTelemetry();
Nota
Para ajudar a garantir que a telemetria do Application Insights funcione conforme o esperado, você deve usar a TargetingHttpContextMiddleware classe.
Para habilitar a persistência do contexto de segmentação na atividade atual, você pode usar a TargetingHttpContextMiddleware classe.
app.UseMiddleware<TargetingHttpContextMiddleware>();
Para obter um exemplo de seu uso, consulte o exemplo VariantAndTelemetryDemo .
Pré-requisito
O editor de telemetria fornecido pelo pacote exige que o Microsoft.FeatureManagement.Telemetry.ApplicationInsights Application Insights seja configurado e registrado como um serviço de aplicativo. Para obter o código de exemplo, consulte o aplicativo de exemplo VariantAndTelemetryDemo .
Colocação em cache
O estado do IConfiguration recurso é fornecido pelo sistema. Espera-se que os provedores de configuração lidem com o armazenamento em cache e a atualização dinâmica. O gerenciador de recursos solicita IConfiguration o valor mais recente do estado de um recurso sempre que avalia se um recurso está habilitado.
Instantâneo
Alguns cenários exigem que o estado de um recurso permaneça consistente durante o tempo de vida de uma solicitação. Os valores retornados de uma implementação padrão IVariantFeatureManager podem mudar se a IConfiguration fonte da qual ela é extraída for atualizada durante a solicitação.
Você pode evitar este comportamento usando IVariantFeatureManagerSnapshot. Você pode recuperar IVariantFeatureManagerSnapshot da mesma maneira que IVariantFeatureManager.
IVariantFeatureManagerSnapshot implementa a IVariantFeatureManager interface, mas IVariantFeatureManagerSnapshot armazena em cache o primeiro estado avaliado de um recurso durante uma solicitação. Isto retorna esse estado durante o tempo de vida da funcionalidade.
Provedores de recursos personalizados
Ao implementar um provedor de recursos personalizado, você pode extrair sinalizadores de recursos de fontes como um banco de dados ou um serviço de gerenciamento de recursos. O provedor de recursos padrão extrai sinalizadores de recursos do sistema de configuração do .NET Core. Esse sistema fornece suporte para definir recursos em um arquivo deappsettings.json ou em provedores de configuração como a Configuração de Aplicativo do Azure. Você pode personalizar esse comportamento para controlar de onde as definições de recurso são lidas.
Para personalizar o carregamento de definições de recursos, você deve implementar a IFeatureDefinitionProvider interface.
public interface IFeatureDefinitionProvider
{
Task<FeatureDefinition> GetFeatureDefinitionAsync(string featureName);
IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync();
}
Para usar uma implementação de IFeatureDefinitionProvider, deve adicioná-la à coleção de serviços antes de adicionar o gerenciamento de recursos. O exemplo a seguir adiciona uma implementação de IFeatureDefinitionProvider named InMemoryFeatureDefinitionProvider.
services.AddSingleton<IFeatureDefinitionProvider, InMemoryFeatureDefinitionProvider>()
.AddFeatureManagement()
Próximos passos
Para descobrir como usar sinalizadores de recursos em seus aplicativos, consulte os seguintes inícios rápidos:
Para saber como usar filtros de recursos, consulte os seguintes tutoriais: