Padrão de opções no ASP.NET CoreOptions pattern in ASP.NET Core

Por Luke LathamBy Luke Latham

O padrão de opções usa classes para representar grupos de configurações relacionadas.The options pattern uses classes to represent groups of related settings. Quando as definições de configuração são isoladas por cenário em classes separadas, o aplicativo segue dois princípios importantes de engenharia de software:When configuration settings are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

As opções também fornecem um mecanismo para validar os dados da configuração.Options also provide a mechanism to validate configuration data. Para obter mais configurações, consulte a seção Validação de opções.For more information, see the Options validation section.

Exibir ou baixar código de exemplo (como baixar)View or download sample code (how to download)

Pré-requisitosPrerequisites

Referencie o metapacote Microsoft.AspNetCore.App ou adicione uma referência de pacote ao pacote Microsoft.Extensions.Options.ConfigurationExtensions.Reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Options.ConfigurationExtensions package.

Interfaces de opçõesOptions interfaces

O IOptionsMonitor<TOptions> é usado para recuperar as opções e gerenciar notificações de opções para instâncias de TOptions.IOptionsMonitor<TOptions> is used to retrieve options and manage options notifications for TOptions instances. O IOptionsMonitor<TOptions> dá suporte aos seguintes cenários:IOptionsMonitor<TOptions> supports the following scenarios:

Os cenários de Pós-configuração permitem que você defina ou altere as opções depois de todas as configurações do IConfigureOptions<TOptions> serem feitas.Post-configuration scenarios allow you to set or change options after all IConfigureOptions<TOptions> configuration occurs.

O IOptionsFactory<TOptions> é responsável por criar novas instâncias de opções.IOptionsFactory<TOptions> is responsible for creating new options instances. Ele tem um único método Create.It has a single Create method. A implementação padrão usa todos os IConfigureOptions<TOptions> e IPostConfigureOptions<TOptions> registrados e executa todas as configurações primeiro, seguidas da pós-configuração.The default implementation takes all registered IConfigureOptions<TOptions> and IPostConfigureOptions<TOptions> and runs all the configurations first, followed by the post-configuration. Ela faz distinção entre IConfigureNamedOptions<TOptions> e IConfigureOptions<TOptions> e chama apenas a interface apropriada.It distinguishes between IConfigureNamedOptions<TOptions> and IConfigureOptions<TOptions> and only calls the appropriate interface.

O IOptionsMonitorCache<TOptions> é usado pelo IOptionsMonitor<TOptions> para armazenar em cache as instâncias do TOptions.IOptionsMonitorCache<TOptions> is used by IOptionsMonitor<TOptions> to cache TOptions instances. O IOptionsMonitorCache<TOptions> invalida as instâncias de opções no monitor, de modo que o valor seja recalculado (TryRemove).The IOptionsMonitorCache<TOptions> invalidates options instances in the monitor so that the value is recomputed (TryRemove). Os valores podem ser manualmente inseridos com TryAdd.Values can be manually introduced with TryAdd. O método Clear é usado quando todas as instâncias nomeadas devem ser recriadas sob demanda.The Clear method is used when all named instances should be recreated on demand.

O IOptionsSnapshot<TOptions> é útil em cenários em que as opções devam ser novamente computadas em cada solicitação.IOptionsSnapshot<TOptions> is useful in scenarios where options should be recomputed on every request. Para saber mais, consulte a seção Recarregar dados de configuração com IOptionsSnapshot.For more information, see the Reload configuration data with IOptionsSnapshot section.

O IOptions<TOptions> pode ser usado para dar suporte a opções.IOptions<TOptions> can be used to support options. No entanto, o IOptions<TOptions> não dá suporte a cenários anteriores do IOptionsMonitor<TOptions>.However, IOptions<TOptions> doesn't support the preceding scenarios of IOptionsMonitor<TOptions>. Você pode continuar a usar o IOptions<TOptions> em estruturas e bibliotecas existentes que já usam a interface do IOptions<TOptions> e não exigem os cenários fornecidos pelo IOptionsMonitor<TOptions>.You may continue to use IOptions<TOptions> in existing frameworks and libraries that already use the IOptions<TOptions> interface and don't require the scenarios provided by IOptionsMonitor<TOptions>.

Configuração de opções geraisGeneral options configuration

A configuração de opções gerais é demonstrada no Exemplo #1 no aplicativo de exemplo.General options configuration is demonstrated as Example #1 in the sample app.

Uma classe de opções deve ser não abstrata e com um construtor público sem parâmetros.An options class must be non-abstract with a public parameterless constructor. A classe a seguir, MyOptions, tem duas propriedades, Option1 e Option2.The following class, MyOptions, has two properties, Option1 and Option2. A configuração de valores padrão é opcional, mas o construtor de classe no exemplo a seguir define o valor padrão de Option1.Setting default values is optional, but the class constructor in the following example sets the default value of Option1. Option2 tem um valor padrão definido com a inicialização da propriedade diretamente (Models/MyOptions.cs):Option2 has a default value set by initializing the property directly (Models/MyOptions.cs):

public class MyOptions
{
    public MyOptions()
    {
        // Set default value.
        Option1 = "value1_from_ctor";
    }
    
    public string Option1 { get; set; }
    public int Option2 { get; set; } = 5;
}

A classe MyOptions é adicionada ao contêiner de serviço com Configure e associada à configuração:The MyOptions class is added to the service container with Configure and bound to configuration:

// Example #1: General configuration
// Register the Configuration instance which MyOptions binds against.
services.Configure<MyOptions>(Configuration);

O seguinte modelo de página usa a injeção de dependência de construtor com IOptionsMonitor<TOptions> para acessar as configurações (Pages/Index.cshtml.cs):The following page model uses constructor dependency injection with IOptionsMonitor<TOptions> to access the settings (Pages/Index.cshtml.cs):

private readonly MyOptions _options;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #1: Simple options
var option1 = _options.Option1;
var option2 = _options.Option2;
SimpleOptions = $"option1 = {option1}, option2 = {option2}";

O arquivo appsettings.json de exemplo especifica valores para option1 e option2:The sample's appsettings.json file specifies values for option1 and option2:

{
  "option1": "value1_from_json",
  "option2": -1,
  "subsection": {
    "suboption1": "subvalue1_from_json",
    "suboption2": 200
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Quando o aplicativo é executado, o método OnGet do modelo de página retorna uma cadeia de caracteres que mostra os valores da classe de opção:When the app is run, the page model's OnGet method returns a string showing the option class values:

option1 = value1_from_json, option2 = -1

Observação

Ao usar um ConfigurationBuilder personalizado para carregar opções de configuração de um arquivo de configurações, confirme se o caminho de base está corretamente configurado:When using a custom ConfigurationBuilder to load options configuration from a settings file, confirm that the base path is set correctly:

var configBuilder = new ConfigurationBuilder()
   .SetBasePath(Directory.GetCurrentDirectory())
   .AddJsonFile("appsettings.json", optional: true);
var config = configBuilder.Build();

services.Configure<MyOptions>(config);

Não é necessário configurar o caminho de base explicitamente ao carregar opções de configuração do arquivo de configurações por meio do CreateDefaultBuilder.Explicitly setting the base path isn't required when loading options configuration from the settings file via CreateDefaultBuilder.

Configurar opções simples com um delegadoConfigure simple options with a delegate

A configuração de opções simples com um delegado é demonstrada no Exemplo #2 no aplicativo de exemplo.Configuring simple options with a delegate is demonstrated as Example #2 in the sample app.

Use um delegado para definir valores de opções.Use a delegate to set options values. O aplicativo de exemplo usa a classe MyOptionsWithDelegateConfig (Models/MyOptionsWithDelegateConfig.cs):The sample app uses the MyOptionsWithDelegateConfig class (Models/MyOptionsWithDelegateConfig.cs):

public class MyOptionsWithDelegateConfig
{
    public MyOptionsWithDelegateConfig()
    {
        // Set default value.
        Option1 = "value1_from_ctor";
    }
    
    public string Option1 { get; set; }
    public int Option2 { get; set; } = 5;
}

No código a seguir, um segundo serviço IConfigureOptions<TOptions> é adicionado ao contêiner de serviço.In the following code, a second IConfigureOptions<TOptions> service is added to the service container. Ele usa um delegado para configurar a associação com MyOptionsWithDelegateConfig:It uses a delegate to configure the binding with MyOptionsWithDelegateConfig:

// Example #2: Options bound and configured by a delegate
services.Configure<MyOptionsWithDelegateConfig>(myOptions =>
{
    myOptions.Option1 = "value1_configured_by_delegate";
    myOptions.Option2 = 500;
});

Index.cshtml.cs:Index.cshtml.cs:

private readonly MyOptionsWithDelegateConfig _optionsWithDelegateConfig;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #2: Options configured by delegate
var delegate_config_option1 = _optionsWithDelegateConfig.Option1;
var delegate_config_option2 = _optionsWithDelegateConfig.Option2;
SimpleOptionsWithDelegateConfig = 
    $"delegate_option1 = {delegate_config_option1}, " +
    $"delegate_option2 = {delegate_config_option2}";

Adicione vários provedores de configuração.You can add multiple configuration providers. Os provedores de configuração estão disponíveis nos pacotes do NuGet e são aplicados na ordem em que são registrados.Configuration providers are available from NuGet packages and are applied in the order that they're registered. Para obter mais informações, consulte Configuração no ASP.NET Core.For more information, see Configuração no ASP.NET Core.

Cada chamada à Configure adiciona um serviço IConfigureOptions<TOptions> ao contêiner de serviço.Each call to Configure adds an IConfigureOptions<TOptions> service to the service container. No exemplo anterior, os valores Option1 e Option2 são especificados em appsettings.json, mas os valores Option1 e Option2 são substituídos pelo delegado configurado.In the preceding example, the values of Option1 and Option2 are both specified in appsettings.json, but the values of Option1 and Option2 are overridden by the configured delegate.

Quando mais de um serviço de configuração é habilitado, a última fonte de configuração especificada vence e define o valor de configuração.When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value. Quando o aplicativo é executado, o método OnGet do modelo de página retorna uma cadeia de caracteres que mostra os valores da classe de opção:When the app is run, the page model's OnGet method returns a string showing the option class values:

delegate_option1 = value1_configured_by_delegate, delegate_option2 = 500

Configuração de subopçõesSuboptions configuration

A configuração de subopções é demonstrada no Exemplo #3 no aplicativo de exemplo.Suboptions configuration is demonstrated as Example #3 in the sample app.

Os aplicativos devem criar classes de opções que pertencem a grupos de cenários específicos (classes) no aplicativo.Apps should create options classes that pertain to specific scenario groups (classes) in the app. Partes do aplicativo que exigem valores de configuração devem ter acesso apenas aos valores de configuração usados por elas.Parts of the app that require configuration values should only have access to the configuration values that they use.

Ao associar opções à configuração, cada propriedade no tipo de opções é associada a uma chave de configuração do formato property[:sub-property:].When binding options to configuration, each property in the options type is bound to a configuration key of the form property[:sub-property:]. Por exemplo, a propriedade MyOptions.Option1 é associada à chave Option1, que é lida da propriedade option1 em appsettings.json.For example, the MyOptions.Option1 property is bound to the key Option1, which is read from the option1 property in appsettings.json.

No código a seguir, um terceiro serviço IConfigureOptions<TOptions> é adicionado ao contêiner de serviço.In the following code, a third IConfigureOptions<TOptions> service is added to the service container. Ele associa MySubOptions à seção subsection do arquivo appsettings.json:It binds MySubOptions to the section subsection of the appsettings.json file:

// Example #3: Suboptions
// Bind options using a sub-section of the appsettings.json file.
services.Configure<MySubOptions>(Configuration.GetSection("subsection"));

O método de extensão GetSection exige o pacote NuGet Microsoft.Extensions.Options.ConfigurationExtensions.The GetSection extension method requires the Microsoft.Extensions.Options.ConfigurationExtensions NuGet package. Se o aplicativo usa o metapacote Microsoft.AspNetCore.App (ASP.NET Core 2.1 ou posterior), o pacote é automaticamente incluído.If the app uses the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later), the package is automatically included.

O arquivo appsettings.json de exemplo define um membro subsection com chaves para suboption1 e suboption2:The sample's appsettings.json file defines a subsection member with keys for suboption1 and suboption2:

{
  "option1": "value1_from_json",
  "option2": -1,
  "subsection": {
    "suboption1": "subvalue1_from_json",
    "suboption2": 200
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

A classe MySubOptions define as propriedades SubOption1 e SubOption2, para armazenar os valores de opções (Models/MySubOptions.cs):The MySubOptions class defines properties, SubOption1 and SubOption2, to hold the options values (Models/MySubOptions.cs):

public class MySubOptions
{
    public MySubOptions()
    {
        // Set default values.
        SubOption1 = "value1_from_ctor";
        SubOption2 = 5;
    }
    
    public string SubOption1 { get; set; }
    public int SubOption2 { get; set; }
}

O método OnGet do modelo da página retorna uma cadeia de caracteres com os valores de opções (Pages/Index.cshtml.cs):The page model's OnGet method returns a string with the options values (Pages/Index.cshtml.cs):

private readonly MySubOptions _subOptions;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #3: Suboptions
var subOption1 = _subOptions.SubOption1;
var subOption2 = _subOptions.SubOption2;
SubOptions = $"subOption1 = {subOption1}, subOption2 = {subOption2}";

Quando o aplicativo é executado, o método OnGet retorna uma cadeia de caracteres que mostra os valores da classe de subopção:When the app is run, the OnGet method returns a string showing the suboption class values:

subOption1 = subvalue1_from_json, subOption2 = 200

Opções fornecidas por um modelo de exibição ou com a injeção de exibição diretaOptions provided by a view model or with direct view injection

As opções fornecidas por um modelo de exibição ou com a injeção de exibição direta são demonstradas no Exemplo #4 no aplicativo de exemplo.Options provided by a view model or with direct view injection is demonstrated as Example #4 in the sample app.

As opções podem ser fornecidas em um modelo de exibição ou pela injeção de IOptionsMonitor<TOptions> diretamente em uma exibição (Pages/Index.cshtml.cs):Options can be supplied in a view model or by injecting IOptionsMonitor<TOptions> directly into a view (Pages/Index.cshtml.cs):

private readonly MyOptions _options;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #4: Bind options directly to the page
MyOptions = _options;

O aplicativo de exemplo mostra como injetar IOptionsMonitor<MyOptions> com uma diretiva @inject:The sample app shows how to inject IOptionsMonitor<MyOptions> with an @inject directive:

@page
@model IndexModel
@using Microsoft.Extensions.Options
@inject IOptionsMonitor<MyOptions> OptionsAccessor
@{
    ViewData["Title"] = "Options Sample";
}

<h1>@ViewData["Title"]</h1>

Quando o aplicativo é executado, os valores de opções são mostrados na página renderizada:When the app is run, the options values are shown in the rendered page:

Os valores de opções Option1: value1_from_json e Option2: -1 são carregados do modelo e pela injeção na exibição.

Recarregar dados de configuração com IOptionsSnapshotReload configuration data with IOptionsSnapshot

O recarregamento de dados de configuração com IOptionsSnapshot<TOptions> é demonstrado no Exemplo #5 no aplicativo de exemplo.Reloading configuration data with IOptionsSnapshot<TOptions> is demonstrated in Example #5 in the sample app.

O IOptionsSnapshot<TOptions> dá suporte a opções de recarregamento com sobrecarga mínima de processamento.IOptionsSnapshot<TOptions> supports reloading options with minimal processing overhead.

As opções são calculadas uma vez por solicitação, quando acessadas e armazenadas em cache durante o tempo de vida da solicitação.Options are computed once per request when accessed and cached for the lifetime of the request.

O exemplo a seguir demonstra como um novo IOptionsSnapshot<TOptions> é criado após a alteração de appsettings.json (Pages/Index.cshtml.cs).The following example demonstrates how a new IOptionsSnapshot<TOptions> is created after appsettings.json changes (Pages/Index.cshtml.cs). Várias solicitações ao servidor retornam valores de constante fornecidos pelo arquivo appsettings.json, até que o arquivo seja alterado e a configuração seja recarregada.Multiple requests to the server return constant values provided by the appsettings.json file until the file is changed and configuration reloads.

private readonly MyOptions _snapshotOptions;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #5: Snapshot options
var snapshotOption1 = _snapshotOptions.Option1;
var snapshotOption2 = _snapshotOptions.Option2;
SnapshotOptions = 
    $"snapshot option1 = {snapshotOption1}, " +
    $"snapshot option2 = {snapshotOption2}";

A seguinte imagem mostra is valores option1 e option2 iniciais carregados do arquivo appsettings.json:The following image shows the initial option1 and option2 values loaded from the appsettings.json file:

snapshot option1 = value1_from_json, snapshot option2 = -1

Altere os valores no arquivo appsettings.json para value1_from_json UPDATED e 200.Change the values in the appsettings.json file to value1_from_json UPDATED and 200. Salve o arquivo appsettings.json.Save the appsettings.json file. Atualize o navegador para ver se os valores de opções foram atualizados:Refresh the browser to see that the options values are updated:

snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200

Suporte de opções nomeadas com IConfigureNamedOptionsNamed options support with IConfigureNamedOptions

O suporte de opções nomeadas com IConfigureNamedOptions<TOptions> é demonstrado como no Exemplo #6 no aplicativo de exemplo.Named options support with IConfigureNamedOptions<TOptions> is demonstrated as Example #6 in the sample app.

O suporte de opções nomeadas permite que o aplicativo faça a distinção entre as configurações de opções nomeadas.Named options support allows the app to distinguish between named options configurations. No aplicativo de exemplo, as opções nomeadas são declaradas com OptionsServiceCollectionExtensions.Configure que chama o método de extensão ConfigureNamedOptions<TOptions>.Configure:In the sample app, named options are declared with OptionsServiceCollectionExtensions.Configure, which calls the ConfigureNamedOptions<TOptions>.Configure extension method:

// Example #6: Named options (named_options_1)
// Register the ConfigurationBuilder instance which MyOptions binds against.
// Specify that the options loaded from configuration are named
// "named_options_1".
services.Configure<MyOptions>("named_options_1", Configuration);

// Example #6: Named options (named_options_2)
// Specify that the options loaded from the MyOptions class are named
// "named_options_2".
// Use a delegate to configure option values.
services.Configure<MyOptions>("named_options_2", myOptions =>
{
    myOptions.Option1 = "named_options_2_value1_from_action";
});

O aplicativo de exemplo acessa as opções nomeadas com Get (Pages/Index.cshtml.cs):The sample app accesses the named options with Get (Pages/Index.cshtml.cs):

private readonly MyOptions _named_options_1;
private readonly MyOptions _named_options_2;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #6: Named options
var named_options_1 = 
    $"named_options_1: option1 = {_named_options_1.Option1}, " +
    $"option2 = {_named_options_1.Option2}";
var named_options_2 = 
    $"named_options_2: option1 = {_named_options_2.Option1}, " +
    $"option2 = {_named_options_2.Option2}";
NamedOptions = $"{named_options_1} {named_options_2}";

Executando o aplicativo de exemplo, as opções nomeadas são retornadas:Running the sample app, the named options are returned:

named_options_1: option1 = value1_from_json, option2 = -1
named_options_2: option1 = named_options_2_value1_from_action, option2 = 5

Os valores named_options_1 são fornecidos pela configuração, que são carregados do arquivo appsettings.json.named_options_1 values are provided from configuration, which are loaded from the appsettings.json file. Os valores named_options_2 são fornecidos pelo:named_options_2 values are provided by:

  • Delegado named_options_2 em ConfigureServices para Option1.The named_options_2 delegate in ConfigureServices for Option1.
  • Valor padrão para Option2 fornecido pela classe MyOptions.The default value for Option2 provided by the MyOptions class.

Configurar todas as opções com o método ConfigureAllConfigure all options with the ConfigureAll method

Configure todas as instâncias de opções com o método ConfigureAll.Configure all options instances with the ConfigureAll method. O código a seguir configura Option1 para todas as instâncias de configuração com um valor comum.The following code configures Option1 for all configuration instances with a common value. Adicione o seguinte código manualmente ao método Startup.ConfigureServices:Add the following code manually to the Startup.ConfigureServices method:

services.ConfigureAll<MyOptions>(myOptions => 
{
    myOptions.Option1 = "ConfigureAll replacement value";
});

A execução do aplicativo de exemplo após a adição do código produz o seguinte resultado:Running the sample app after adding the code produces the following result:

named_options_1: option1 = ConfigureAll replacement value, option2 = -1
named_options_2: option1 = ConfigureAll replacement value, option2 = 5

Observação

Todas as opções são instâncias nomeadas.All options are named instances. As instâncias IConfigureOptions<TOptions> existentes são tratadas como sendo direcionadas à instância Options.DefaultName, que é string.Empty.Existing IConfigureOptions<TOptions> instances are treated as targeting the Options.DefaultName instance, which is string.Empty. IConfigureNamedOptions<TOptions> também implementa IConfigureOptions<TOptions>.IConfigureNamedOptions<TOptions> also implements IConfigureOptions<TOptions>. A implementação padrão de IOptionsFactory<TOptions> tem lógica para usar cada um de forma adequada.The default implementation of the IOptionsFactory<TOptions> has logic to use each appropriately. A opção nomeada null é usada para direcionar todas as instâncias nomeadas, em vez de uma instância nomeada específica (ConfigureAll e PostConfigureAll usam essa convenção).The null named option is used to target all of the named instances instead of a specific named instance (ConfigureAll and PostConfigureAll use this convention).

API OptionsBuilderOptionsBuilder API

OptionsBuilder<TOptions> é usada para configurar instâncias TOptions.OptionsBuilder<TOptions> is used to configure TOptions instances. OptionsBuilder simplifica a criação de opções nomeadas, pois é apenas um único parâmetro para a chamada AddOptions<TOptions>(string optionsName) inicial, em vez de aparecer em todas as chamadas subsequentes.OptionsBuilder streamlines creating named options as it's only a single parameter to the initial AddOptions<TOptions>(string optionsName) call instead of appearing in all of the subsequent calls. A validação de opções e as sobrecargas ConfigureOptions que aceitam dependências de serviço só estão disponíveis por meio de OptionsBuilder.Options validation and the ConfigureOptions overloads that accept service dependencies are only available via OptionsBuilder.

// Options.DefaultName = "" is used.
services.AddOptions<MyOptions>().Configure(o => o.Property = "default");

services.AddOptions<MyOptions>("optionalName")
    .Configure(o => o.Property = "named");

Usar os serviços de injeção de dependência para configurar as opçõesUse DI services to configure options

Você pode acessar outros serviços de injeção de dependência ao configurar as opções de duas maneiras:You can access other services from dependency injection while configuring options in two ways:

É recomendável transmitir um delegado de configuração para Configurar, já que a criação de um serviço é algo mais complexo.We recommend passing a configuration delegate to Configure, since creating a service is more complex. Criar seu próprio tipo é equivalente ao que a estrutura faz para você quando você usa Configure.Creating your own type is equivalent to what the framework does for you when you use Configure. Chamar Configure registra um genérico transitório IConfigureNamedOptions<TOptions>, que tem um construtor que aceita os tipos de serviço genérico especificados.Calling Configure registers a transient generic IConfigureNamedOptions<TOptions>, which has a constructor that accepts the generic service types specified.

Validação de opçõesOptions validation

A validação de opções permite validar as opções depois de configurá-las.Options validation allows you to validate options when options are configured. Chame Validate com um método de validação que retorna true quando as opções são válidas, e false quando não são:Call Validate with a validation method that returns true if options are valid and false if they aren't valid:

// Registration
services.AddOptions<MyOptions>("optionalOptionsName")
    .Configure(o => { }) // Configure the options
    .Validate(o => YourValidationShouldReturnTrueIfValid(o), 
        "custom error");

// Consumption
var monitor = services.BuildServiceProvider()
    .GetService<IOptionsMonitor<MyOptions>>();

try
{
    var options = monitor.Get("optionalOptionsName");
}
catch (OptionsValidationException e) 
{
   // e.OptionsName returns "optionalOptionsName"
   // e.OptionsType returns typeof(MyOptions)
   // e.Failures returns a list of errors, which would contain 
   //     "custom error"
}

O exemplo anterior define a instância de opções nomeadas como optionalOptionsName.The preceding example sets the named options instance to optionalOptionsName. A instância de opções padrão é Options.DefaultName.The default options instance is Options.DefaultName.

A validação é executada após a criação da instância de opções.Validation runs when the options instance is created. A instância de opções tem garantia de passar pela validação, na primeira vez em que for acessada.Your options instance is guaranteed to pass validation the first time it's accessed.

Importante

A validação não protege contra modificações de opções, depois que as opções são inicialmente configuradas e validadas.Options validation doesn't guard against options modifications after the options are initially configured and validated.

O método Validate aceita um Func<TOptions, bool>.The Validate method accepts a Func<TOptions, bool>. Para personalizar totalmente a validação, implemente IValidateOptions<TOptions>, que permite:To fully customize validation, implement IValidateOptions<TOptions>, which allows:

  • A validação de vários tipos de opções: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>Validation of multiple options types: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>
  • A validação que depende de outro tipo de opção: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)Validation that depends on another option type: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)

IValidateOptions valida:IValidateOptions validates:

  • Uma instância específica de opções nomeadas.A specific named options instance.
  • Todas as opções quando name for null.All options when name is null.

Retornar um ValidateOptionsResult da implementação da interface:Return a ValidateOptionsResult from your implementation of the interface:

public interface IValidateOptions<TOptions> where TOptions : class
{
    ValidateOptionsResult Validate(string name, TOptions options);
}

A validação de anotação de dados está disponível no pacote Microsoft.Extensions.Options.DataAnnotations por meio da chamada do método ValidateDataAnnotations em OptionsBuilder<TOptions>.Data Annotation-based validation is available from the Microsoft.Extensions.Options.DataAnnotations package by calling the ValidateDataAnnotations method on OptionsBuilder<TOptions>. O Microsoft.Extensions.Options.DataAnnotations está incluído no metapacote Microsoft.AspNetCore.App (ASP.NET Core 2.2 ou posterior).Microsoft.Extensions.Options.DataAnnotations is included in the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.2 or later).

using Microsoft.Extensions.DependencyInjection;

private class AnnotatedOptions
{
    [Required]
    public string Required { get; set; }

    [StringLength(5, ErrorMessage = "Too long.")]
    public string StringLength { get; set; }

    [Range(-5, 5, ErrorMessage = "Out of range.")]
    public int IntRange { get; set; }
}

[Fact]
public void CanValidateDataAnnotations()
{
    var services = new ServiceCollection();
    services.AddOptions<AnnotatedOptions>()
        .Configure(o =>
        {
            o.StringLength = "111111";
            o.IntRange = 10;
            o.Custom = "nowhere";
        })
        .ValidateDataAnnotations();

    var sp = services.BuildServiceProvider();

    var error = Assert.Throws<OptionsValidationException>(() => 
        sp.GetRequiredService<IOptionsMonitor<AnnotatedOptions>>().Value);
    ValidateFailure<AnnotatedOptions>(error, Options.DefaultName, 1,
        "DataAnnotation validation failed for members Required " +
            "with the error 'The Required field is required.'.",
        "DataAnnotation validation failed for members StringLength " +
            "with the error 'Too long.'.",
        "DataAnnotation validation failed for members IntRange " +
            "with the error 'Out of range.'.");
}

A validação adiantada (fail fast na inicialização) está sendo considerada para uma versão futura.Eager validation (fail fast at startup) is under consideration for a future release.

Pós-configuração de opçõesOptions post-configuration

Defina a pós-configuração com IPostConfigureOptions<TOptions>.Set post-configuration with IPostConfigureOptions<TOptions>. A pós-configuração é executada depois que toda o configuração de IConfigureOptions<TOptions> é feita:Post-configuration runs after all IConfigureOptions<TOptions> configuration occurs:

services.PostConfigure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

O PostConfigure está disponível para pós-configurar opções nomeadas:PostConfigure is available to post-configure named options:

services.PostConfigure<MyOptions>("named_options_1", myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

Use PostConfigureAll para pós-configurar todas as instâncias de configuração:Use PostConfigureAll to post-configure all configuration instances:

services.PostConfigureAll<MyOptions>(myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

Acessando opções durante a inicializaçãoAccessing options during startup

IOptions<TOptions> e IOptionsMonitor<TOptions> podem ser usados em Startup.Configure, pois os serviços são criados antes da execução do método Configure.IOptions<TOptions> and IOptionsMonitor<TOptions> can be used in Startup.Configure, since services are built before the Configure method executes.

public void Configure(IApplicationBuilder app, IOptionsMonitor<MyOptions> optionsAccessor)
{
    var option1 = optionsAccessor.CurrentValue.Option1;
}

Não use IOptions<TOptions> ou IOptionsMonitor<TOptions> em Startup.ConfigureServices.Don't use IOptions<TOptions> or IOptionsMonitor<TOptions> in Startup.ConfigureServices. Pode haver um estado inconsistente de opções devido à ordenação dos registros de serviço.An inconsistent options state may exist due to the ordering of service registrations.

O padrão de opções usa classes para representar grupos de configurações relacionadas.The options pattern uses classes to represent groups of related settings. Quando as definições de configuração são isoladas por cenário em classes separadas, o aplicativo segue dois princípios importantes de engenharia de software:When configuration settings are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

As opções também fornecem um mecanismo para validar os dados da configuração.Options also provide a mechanism to validate configuration data. Para obter mais configurações, consulte a seção Validação de opções.For more information, see the Options validation section.

Exibir ou baixar código de exemplo (como baixar)View or download sample code (how to download)

Pré-requisitosPrerequisites

Referencie o metapacote Microsoft.AspNetCore.App ou adicione uma referência de pacote ao pacote Microsoft.Extensions.Options.ConfigurationExtensions.Reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Options.ConfigurationExtensions package.

Interfaces de opçõesOptions interfaces

O IOptionsMonitor<TOptions> é usado para recuperar as opções e gerenciar notificações de opções para instâncias de TOptions.IOptionsMonitor<TOptions> is used to retrieve options and manage options notifications for TOptions instances. O IOptionsMonitor<TOptions> dá suporte aos seguintes cenários:IOptionsMonitor<TOptions> supports the following scenarios:

Os cenários de Pós-configuração permitem que você defina ou altere as opções depois de todas as configurações do IConfigureOptions<TOptions> serem feitas.Post-configuration scenarios allow you to set or change options after all IConfigureOptions<TOptions> configuration occurs.

O IOptionsFactory<TOptions> é responsável por criar novas instâncias de opções.IOptionsFactory<TOptions> is responsible for creating new options instances. Ele tem um único método Create.It has a single Create method. A implementação padrão usa todos os IConfigureOptions<TOptions> e IPostConfigureOptions<TOptions> registrados e executa todas as configurações primeiro, seguidas da pós-configuração.The default implementation takes all registered IConfigureOptions<TOptions> and IPostConfigureOptions<TOptions> and runs all the configurations first, followed by the post-configuration. Ela faz distinção entre IConfigureNamedOptions<TOptions> e IConfigureOptions<TOptions> e chama apenas a interface apropriada.It distinguishes between IConfigureNamedOptions<TOptions> and IConfigureOptions<TOptions> and only calls the appropriate interface.

O IOptionsMonitorCache<TOptions> é usado pelo IOptionsMonitor<TOptions> para armazenar em cache as instâncias do TOptions.IOptionsMonitorCache<TOptions> is used by IOptionsMonitor<TOptions> to cache TOptions instances. O IOptionsMonitorCache<TOptions> invalida as instâncias de opções no monitor, de modo que o valor seja recalculado (TryRemove).The IOptionsMonitorCache<TOptions> invalidates options instances in the monitor so that the value is recomputed (TryRemove). Os valores podem ser manualmente inseridos com TryAdd.Values can be manually introduced with TryAdd. O método Clear é usado quando todas as instâncias nomeadas devem ser recriadas sob demanda.The Clear method is used when all named instances should be recreated on demand.

O IOptionsSnapshot<TOptions> é útil em cenários em que as opções devam ser novamente computadas em cada solicitação.IOptionsSnapshot<TOptions> is useful in scenarios where options should be recomputed on every request. Para saber mais, consulte a seção Recarregar dados de configuração com IOptionsSnapshot.For more information, see the Reload configuration data with IOptionsSnapshot section.

O IOptions<TOptions> pode ser usado para dar suporte a opções.IOptions<TOptions> can be used to support options. No entanto, o IOptions<TOptions> não dá suporte a cenários anteriores do IOptionsMonitor<TOptions>.However, IOptions<TOptions> doesn't support the preceding scenarios of IOptionsMonitor<TOptions>. Você pode continuar a usar o IOptions<TOptions> em estruturas e bibliotecas existentes que já usam a interface do IOptions<TOptions> e não exigem os cenários fornecidos pelo IOptionsMonitor<TOptions>.You may continue to use IOptions<TOptions> in existing frameworks and libraries that already use the IOptions<TOptions> interface and don't require the scenarios provided by IOptionsMonitor<TOptions>.

Configuração de opções geraisGeneral options configuration

A configuração de opções gerais é demonstrada no Exemplo #1 no aplicativo de exemplo.General options configuration is demonstrated as Example #1 in the sample app.

Uma classe de opções deve ser não abstrata e com um construtor público sem parâmetros.An options class must be non-abstract with a public parameterless constructor. A classe a seguir, MyOptions, tem duas propriedades, Option1 e Option2.The following class, MyOptions, has two properties, Option1 and Option2. A configuração de valores padrão é opcional, mas o construtor de classe no exemplo a seguir define o valor padrão de Option1.Setting default values is optional, but the class constructor in the following example sets the default value of Option1. Option2 tem um valor padrão definido com a inicialização da propriedade diretamente (Models/MyOptions.cs):Option2 has a default value set by initializing the property directly (Models/MyOptions.cs):

public class MyOptions
{
    public MyOptions()
    {
        // Set default value.
        Option1 = "value1_from_ctor";
    }
    
    public string Option1 { get; set; }
    public int Option2 { get; set; } = 5;
}

A classe MyOptions é adicionada ao contêiner de serviço com Configure e associada à configuração:The MyOptions class is added to the service container with Configure and bound to configuration:

// Example #1: General configuration
// Register the Configuration instance which MyOptions binds against.
services.Configure<MyOptions>(Configuration);

O seguinte modelo de página usa a injeção de dependência de construtor com IOptionsMonitor<TOptions> para acessar as configurações (Pages/Index.cshtml.cs):The following page model uses constructor dependency injection with IOptionsMonitor<TOptions> to access the settings (Pages/Index.cshtml.cs):

private readonly MyOptions _options;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #1: Simple options
var option1 = _options.Option1;
var option2 = _options.Option2;
SimpleOptions = $"option1 = {option1}, option2 = {option2}";

O arquivo appsettings.json de exemplo especifica valores para option1 e option2:The sample's appsettings.json file specifies values for option1 and option2:

{
  "option1": "value1_from_json",
  "option2": -1,
  "subsection": {
    "suboption1": "subvalue1_from_json",
    "suboption2": 200
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Quando o aplicativo é executado, o método OnGet do modelo de página retorna uma cadeia de caracteres que mostra os valores da classe de opção:When the app is run, the page model's OnGet method returns a string showing the option class values:

option1 = value1_from_json, option2 = -1

Observação

Ao usar um ConfigurationBuilder personalizado para carregar opções de configuração de um arquivo de configurações, confirme se o caminho de base está corretamente configurado:When using a custom ConfigurationBuilder to load options configuration from a settings file, confirm that the base path is set correctly:

var configBuilder = new ConfigurationBuilder()
   .SetBasePath(Directory.GetCurrentDirectory())
   .AddJsonFile("appsettings.json", optional: true);
var config = configBuilder.Build();

services.Configure<MyOptions>(config);

Não é necessário configurar o caminho de base explicitamente ao carregar opções de configuração do arquivo de configurações por meio do CreateDefaultBuilder.Explicitly setting the base path isn't required when loading options configuration from the settings file via CreateDefaultBuilder.

Configurar opções simples com um delegadoConfigure simple options with a delegate

A configuração de opções simples com um delegado é demonstrada no Exemplo #2 no aplicativo de exemplo.Configuring simple options with a delegate is demonstrated as Example #2 in the sample app.

Use um delegado para definir valores de opções.Use a delegate to set options values. O aplicativo de exemplo usa a classe MyOptionsWithDelegateConfig (Models/MyOptionsWithDelegateConfig.cs):The sample app uses the MyOptionsWithDelegateConfig class (Models/MyOptionsWithDelegateConfig.cs):

public class MyOptionsWithDelegateConfig
{
    public MyOptionsWithDelegateConfig()
    {
        // Set default value.
        Option1 = "value1_from_ctor";
    }
    
    public string Option1 { get; set; }
    public int Option2 { get; set; } = 5;
}

No código a seguir, um segundo serviço IConfigureOptions<TOptions> é adicionado ao contêiner de serviço.In the following code, a second IConfigureOptions<TOptions> service is added to the service container. Ele usa um delegado para configurar a associação com MyOptionsWithDelegateConfig:It uses a delegate to configure the binding with MyOptionsWithDelegateConfig:

// Example #2: Options bound and configured by a delegate
services.Configure<MyOptionsWithDelegateConfig>(myOptions =>
{
    myOptions.Option1 = "value1_configured_by_delegate";
    myOptions.Option2 = 500;
});

Index.cshtml.cs:Index.cshtml.cs:

private readonly MyOptionsWithDelegateConfig _optionsWithDelegateConfig;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #2: Options configured by delegate
var delegate_config_option1 = _optionsWithDelegateConfig.Option1;
var delegate_config_option2 = _optionsWithDelegateConfig.Option2;
SimpleOptionsWithDelegateConfig = 
    $"delegate_option1 = {delegate_config_option1}, " +
    $"delegate_option2 = {delegate_config_option2}";

Adicione vários provedores de configuração.You can add multiple configuration providers. Os provedores de configuração estão disponíveis nos pacotes do NuGet e são aplicados na ordem em que são registrados.Configuration providers are available from NuGet packages and are applied in the order that they're registered. Para obter mais informações, consulte Configuração no ASP.NET Core.For more information, see Configuração no ASP.NET Core.

Cada chamada à Configure adiciona um serviço IConfigureOptions<TOptions> ao contêiner de serviço.Each call to Configure adds an IConfigureOptions<TOptions> service to the service container. No exemplo anterior, os valores Option1 e Option2 são especificados em appsettings.json, mas os valores Option1 e Option2 são substituídos pelo delegado configurado.In the preceding example, the values of Option1 and Option2 are both specified in appsettings.json, but the values of Option1 and Option2 are overridden by the configured delegate.

Quando mais de um serviço de configuração é habilitado, a última fonte de configuração especificada vence e define o valor de configuração.When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value. Quando o aplicativo é executado, o método OnGet do modelo de página retorna uma cadeia de caracteres que mostra os valores da classe de opção:When the app is run, the page model's OnGet method returns a string showing the option class values:

delegate_option1 = value1_configured_by_delegate, delegate_option2 = 500

Configuração de subopçõesSuboptions configuration

A configuração de subopções é demonstrada no Exemplo #3 no aplicativo de exemplo.Suboptions configuration is demonstrated as Example #3 in the sample app.

Os aplicativos devem criar classes de opções que pertencem a grupos de cenários específicos (classes) no aplicativo.Apps should create options classes that pertain to specific scenario groups (classes) in the app. Partes do aplicativo que exigem valores de configuração devem ter acesso apenas aos valores de configuração usados por elas.Parts of the app that require configuration values should only have access to the configuration values that they use.

Ao associar opções à configuração, cada propriedade no tipo de opções é associada a uma chave de configuração do formato property[:sub-property:].When binding options to configuration, each property in the options type is bound to a configuration key of the form property[:sub-property:]. Por exemplo, a propriedade MyOptions.Option1 é associada à chave Option1, que é lida da propriedade option1 em appsettings.json.For example, the MyOptions.Option1 property is bound to the key Option1, which is read from the option1 property in appsettings.json.

No código a seguir, um terceiro serviço IConfigureOptions<TOptions> é adicionado ao contêiner de serviço.In the following code, a third IConfigureOptions<TOptions> service is added to the service container. Ele associa MySubOptions à seção subsection do arquivo appsettings.json:It binds MySubOptions to the section subsection of the appsettings.json file:

// Example #3: Suboptions
// Bind options using a sub-section of the appsettings.json file.
services.Configure<MySubOptions>(Configuration.GetSection("subsection"));

O método de extensão GetSection exige o pacote NuGet Microsoft.Extensions.Options.ConfigurationExtensions.The GetSection extension method requires the Microsoft.Extensions.Options.ConfigurationExtensions NuGet package. Se o aplicativo usa o metapacote Microsoft.AspNetCore.App (ASP.NET Core 2.1 ou posterior), o pacote é automaticamente incluído.If the app uses the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later), the package is automatically included.

O arquivo appsettings.json de exemplo define um membro subsection com chaves para suboption1 e suboption2:The sample's appsettings.json file defines a subsection member with keys for suboption1 and suboption2:

{
  "option1": "value1_from_json",
  "option2": -1,
  "subsection": {
    "suboption1": "subvalue1_from_json",
    "suboption2": 200
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

A classe MySubOptions define as propriedades SubOption1 e SubOption2, para armazenar os valores de opções (Models/MySubOptions.cs):The MySubOptions class defines properties, SubOption1 and SubOption2, to hold the options values (Models/MySubOptions.cs):

public class MySubOptions
{
    public MySubOptions()
    {
        // Set default values.
        SubOption1 = "value1_from_ctor";
        SubOption2 = 5;
    }
    
    public string SubOption1 { get; set; }
    public int SubOption2 { get; set; }
}

O método OnGet do modelo da página retorna uma cadeia de caracteres com os valores de opções (Pages/Index.cshtml.cs):The page model's OnGet method returns a string with the options values (Pages/Index.cshtml.cs):

private readonly MySubOptions _subOptions;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #3: Suboptions
var subOption1 = _subOptions.SubOption1;
var subOption2 = _subOptions.SubOption2;
SubOptions = $"subOption1 = {subOption1}, subOption2 = {subOption2}";

Quando o aplicativo é executado, o método OnGet retorna uma cadeia de caracteres que mostra os valores da classe de subopção:When the app is run, the OnGet method returns a string showing the suboption class values:

subOption1 = subvalue1_from_json, subOption2 = 200

Opções fornecidas por um modelo de exibição ou com a injeção de exibição diretaOptions provided by a view model or with direct view injection

As opções fornecidas por um modelo de exibição ou com a injeção de exibição direta são demonstradas no Exemplo #4 no aplicativo de exemplo.Options provided by a view model or with direct view injection is demonstrated as Example #4 in the sample app.

As opções podem ser fornecidas em um modelo de exibição ou pela injeção de IOptionsMonitor<TOptions> diretamente em uma exibição (Pages/Index.cshtml.cs):Options can be supplied in a view model or by injecting IOptionsMonitor<TOptions> directly into a view (Pages/Index.cshtml.cs):

private readonly MyOptions _options;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #4: Bind options directly to the page
MyOptions = _options;

O aplicativo de exemplo mostra como injetar IOptionsMonitor<MyOptions> com uma diretiva @inject:The sample app shows how to inject IOptionsMonitor<MyOptions> with an @inject directive:

@page
@model IndexModel
@using Microsoft.Extensions.Options
@inject IOptionsMonitor<MyOptions> OptionsAccessor
@{
    ViewData["Title"] = "Options Sample";
}

<h1>@ViewData["Title"]</h1>

Quando o aplicativo é executado, os valores de opções são mostrados na página renderizada:When the app is run, the options values are shown in the rendered page:

Os valores de opções Option1: value1_from_json e Option2: -1 são carregados do modelo e pela injeção na exibição.

Recarregar dados de configuração com IOptionsSnapshotReload configuration data with IOptionsSnapshot

O recarregamento de dados de configuração com IOptionsSnapshot<TOptions> é demonstrado no Exemplo #5 no aplicativo de exemplo.Reloading configuration data with IOptionsSnapshot<TOptions> is demonstrated in Example #5 in the sample app.

O IOptionsSnapshot<TOptions> dá suporte a opções de recarregamento com sobrecarga mínima de processamento.IOptionsSnapshot<TOptions> supports reloading options with minimal processing overhead.

As opções são calculadas uma vez por solicitação, quando acessadas e armazenadas em cache durante o tempo de vida da solicitação.Options are computed once per request when accessed and cached for the lifetime of the request.

O exemplo a seguir demonstra como um novo IOptionsSnapshot<TOptions> é criado após a alteração de appsettings.json (Pages/Index.cshtml.cs).The following example demonstrates how a new IOptionsSnapshot<TOptions> is created after appsettings.json changes (Pages/Index.cshtml.cs). Várias solicitações ao servidor retornam valores de constante fornecidos pelo arquivo appsettings.json, até que o arquivo seja alterado e a configuração seja recarregada.Multiple requests to the server return constant values provided by the appsettings.json file until the file is changed and configuration reloads.

private readonly MyOptions _snapshotOptions;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #5: Snapshot options
var snapshotOption1 = _snapshotOptions.Option1;
var snapshotOption2 = _snapshotOptions.Option2;
SnapshotOptions = 
    $"snapshot option1 = {snapshotOption1}, " +
    $"snapshot option2 = {snapshotOption2}";

A seguinte imagem mostra is valores option1 e option2 iniciais carregados do arquivo appsettings.json:The following image shows the initial option1 and option2 values loaded from the appsettings.json file:

snapshot option1 = value1_from_json, snapshot option2 = -1

Altere os valores no arquivo appsettings.json para value1_from_json UPDATED e 200.Change the values in the appsettings.json file to value1_from_json UPDATED and 200. Salve o arquivo appsettings.json.Save the appsettings.json file. Atualize o navegador para ver se os valores de opções foram atualizados:Refresh the browser to see that the options values are updated:

snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200

Suporte de opções nomeadas com IConfigureNamedOptionsNamed options support with IConfigureNamedOptions

O suporte de opções nomeadas com IConfigureNamedOptions<TOptions> é demonstrado como no Exemplo #6 no aplicativo de exemplo.Named options support with IConfigureNamedOptions<TOptions> is demonstrated as Example #6 in the sample app.

O suporte de opções nomeadas permite que o aplicativo faça a distinção entre as configurações de opções nomeadas.Named options support allows the app to distinguish between named options configurations. No aplicativo de exemplo, as opções nomeadas são declaradas com OptionsServiceCollectionExtensions.Configure que chama o método de extensão ConfigureNamedOptions<TOptions>.Configure:In the sample app, named options are declared with OptionsServiceCollectionExtensions.Configure, which calls the ConfigureNamedOptions<TOptions>.Configure extension method:

// Example #6: Named options (named_options_1)
// Register the ConfigurationBuilder instance which MyOptions binds against.
// Specify that the options loaded from configuration are named
// "named_options_1".
services.Configure<MyOptions>("named_options_1", Configuration);

// Example #6: Named options (named_options_2)
// Specify that the options loaded from the MyOptions class are named
// "named_options_2".
// Use a delegate to configure option values.
services.Configure<MyOptions>("named_options_2", myOptions =>
{
    myOptions.Option1 = "named_options_2_value1_from_action";
});

O aplicativo de exemplo acessa as opções nomeadas com Get (Pages/Index.cshtml.cs):The sample app accesses the named options with Get (Pages/Index.cshtml.cs):

private readonly MyOptions _named_options_1;
private readonly MyOptions _named_options_2;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #6: Named options
var named_options_1 = 
    $"named_options_1: option1 = {_named_options_1.Option1}, " +
    $"option2 = {_named_options_1.Option2}";
var named_options_2 = 
    $"named_options_2: option1 = {_named_options_2.Option1}, " +
    $"option2 = {_named_options_2.Option2}";
NamedOptions = $"{named_options_1} {named_options_2}";

Executando o aplicativo de exemplo, as opções nomeadas são retornadas:Running the sample app, the named options are returned:

named_options_1: option1 = value1_from_json, option2 = -1
named_options_2: option1 = named_options_2_value1_from_action, option2 = 5

Os valores named_options_1 são fornecidos pela configuração, que são carregados do arquivo appsettings.json.named_options_1 values are provided from configuration, which are loaded from the appsettings.json file. Os valores named_options_2 são fornecidos pelo:named_options_2 values are provided by:

  • Delegado named_options_2 em ConfigureServices para Option1.The named_options_2 delegate in ConfigureServices for Option1.
  • Valor padrão para Option2 fornecido pela classe MyOptions.The default value for Option2 provided by the MyOptions class.

Configurar todas as opções com o método ConfigureAllConfigure all options with the ConfigureAll method

Configure todas as instâncias de opções com o método ConfigureAll.Configure all options instances with the ConfigureAll method. O código a seguir configura Option1 para todas as instâncias de configuração com um valor comum.The following code configures Option1 for all configuration instances with a common value. Adicione o seguinte código manualmente ao método Startup.ConfigureServices:Add the following code manually to the Startup.ConfigureServices method:

services.ConfigureAll<MyOptions>(myOptions => 
{
    myOptions.Option1 = "ConfigureAll replacement value";
});

A execução do aplicativo de exemplo após a adição do código produz o seguinte resultado:Running the sample app after adding the code produces the following result:

named_options_1: option1 = ConfigureAll replacement value, option2 = -1
named_options_2: option1 = ConfigureAll replacement value, option2 = 5

Observação

Todas as opções são instâncias nomeadas.All options are named instances. As instâncias IConfigureOptions<TOptions> existentes são tratadas como sendo direcionadas à instância Options.DefaultName, que é string.Empty.Existing IConfigureOptions<TOptions> instances are treated as targeting the Options.DefaultName instance, which is string.Empty. IConfigureNamedOptions<TOptions> também implementa IConfigureOptions<TOptions>.IConfigureNamedOptions<TOptions> also implements IConfigureOptions<TOptions>. A implementação padrão de IOptionsFactory<TOptions> tem lógica para usar cada um de forma adequada.The default implementation of the IOptionsFactory<TOptions> has logic to use each appropriately. A opção nomeada null é usada para direcionar todas as instâncias nomeadas, em vez de uma instância nomeada específica (ConfigureAll e PostConfigureAll usam essa convenção).The null named option is used to target all of the named instances instead of a specific named instance (ConfigureAll and PostConfigureAll use this convention).

API OptionsBuilderOptionsBuilder API

OptionsBuilder<TOptions> é usada para configurar instâncias TOptions.OptionsBuilder<TOptions> is used to configure TOptions instances. OptionsBuilder simplifica a criação de opções nomeadas, pois é apenas um único parâmetro para a chamada AddOptions<TOptions>(string optionsName) inicial, em vez de aparecer em todas as chamadas subsequentes.OptionsBuilder streamlines creating named options as it's only a single parameter to the initial AddOptions<TOptions>(string optionsName) call instead of appearing in all of the subsequent calls. A validação de opções e as sobrecargas ConfigureOptions que aceitam dependências de serviço só estão disponíveis por meio de OptionsBuilder.Options validation and the ConfigureOptions overloads that accept service dependencies are only available via OptionsBuilder.

// Options.DefaultName = "" is used.
services.AddOptions<MyOptions>().Configure(o => o.Property = "default");

services.AddOptions<MyOptions>("optionalName")
    .Configure(o => o.Property = "named");

Usar os serviços de injeção de dependência para configurar as opçõesUse DI services to configure options

Você pode acessar outros serviços de injeção de dependência ao configurar as opções de duas maneiras:You can access other services from dependency injection while configuring options in two ways:

É recomendável transmitir um delegado de configuração para Configurar, já que a criação de um serviço é algo mais complexo.We recommend passing a configuration delegate to Configure, since creating a service is more complex. Criar seu próprio tipo é equivalente ao que a estrutura faz para você quando você usa Configure.Creating your own type is equivalent to what the framework does for you when you use Configure. Chamar Configure registra um genérico transitório IConfigureNamedOptions<TOptions>, que tem um construtor que aceita os tipos de serviço genérico especificados.Calling Configure registers a transient generic IConfigureNamedOptions<TOptions>, which has a constructor that accepts the generic service types specified.

Validação de opçõesOptions validation

A validação de opções permite validar as opções depois de configurá-las.Options validation allows you to validate options when options are configured. Chame Validate com um método de validação que retorna true quando as opções são válidas, e false quando não são:Call Validate with a validation method that returns true if options are valid and false if they aren't valid:

// Registration
services.AddOptions<MyOptions>("optionalOptionsName")
    .Configure(o => { }) // Configure the options
    .Validate(o => YourValidationShouldReturnTrueIfValid(o), 
        "custom error");

// Consumption
var monitor = services.BuildServiceProvider()
    .GetService<IOptionsMonitor<MyOptions>>();

try
{
    var options = monitor.Get("optionalOptionsName");
}
catch (OptionsValidationException e) 
{
   // e.OptionsName returns "optionalOptionsName"
   // e.OptionsType returns typeof(MyOptions)
   // e.Failures returns a list of errors, which would contain 
   //     "custom error"
}

O exemplo anterior define a instância de opções nomeadas como optionalOptionsName.The preceding example sets the named options instance to optionalOptionsName. A instância de opções padrão é Options.DefaultName.The default options instance is Options.DefaultName.

A validação é executada após a criação da instância de opções.Validation runs when the options instance is created. A instância de opções tem garantia de passar pela validação, na primeira vez em que for acessada.Your options instance is guaranteed to pass validation the first time it's accessed.

Importante

A validação não protege contra modificações de opções, depois que as opções são inicialmente configuradas e validadas.Options validation doesn't guard against options modifications after the options are initially configured and validated.

O método Validate aceita um Func<TOptions, bool>.The Validate method accepts a Func<TOptions, bool>. Para personalizar totalmente a validação, implemente IValidateOptions<TOptions>, que permite:To fully customize validation, implement IValidateOptions<TOptions>, which allows:

  • A validação de vários tipos de opções: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>Validation of multiple options types: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>
  • A validação que depende de outro tipo de opção: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)Validation that depends on another option type: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)

IValidateOptions valida:IValidateOptions validates:

  • Uma instância específica de opções nomeadas.A specific named options instance.
  • Todas as opções quando name for null.All options when name is null.

Retornar um ValidateOptionsResult da implementação da interface:Return a ValidateOptionsResult from your implementation of the interface:

public interface IValidateOptions<TOptions> where TOptions : class
{
    ValidateOptionsResult Validate(string name, TOptions options);
}

A validação de anotação de dados está disponível no pacote Microsoft.Extensions.Options.DataAnnotations por meio da chamada do método ValidateDataAnnotations em OptionsBuilder<TOptions>.Data Annotation-based validation is available from the Microsoft.Extensions.Options.DataAnnotations package by calling the ValidateDataAnnotations method on OptionsBuilder<TOptions>. O Microsoft.Extensions.Options.DataAnnotations está incluído no metapacote Microsoft.AspNetCore.App (ASP.NET Core 2.2 ou posterior).Microsoft.Extensions.Options.DataAnnotations is included in the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.2 or later).

using Microsoft.Extensions.DependencyInjection;

private class AnnotatedOptions
{
    [Required]
    public string Required { get; set; }

    [StringLength(5, ErrorMessage = "Too long.")]
    public string StringLength { get; set; }

    [Range(-5, 5, ErrorMessage = "Out of range.")]
    public int IntRange { get; set; }
}

[Fact]
public void CanValidateDataAnnotations()
{
    var services = new ServiceCollection();
    services.AddOptions<AnnotatedOptions>()
        .Configure(o =>
        {
            o.StringLength = "111111";
            o.IntRange = 10;
            o.Custom = "nowhere";
        })
        .ValidateDataAnnotations();

    var sp = services.BuildServiceProvider();

    var error = Assert.Throws<OptionsValidationException>(() => 
        sp.GetRequiredService<IOptionsMonitor<AnnotatedOptions>>().Value);
    ValidateFailure<AnnotatedOptions>(error, Options.DefaultName, 1,
        "DataAnnotation validation failed for members Required " +
            "with the error 'The Required field is required.'.",
        "DataAnnotation validation failed for members StringLength " +
            "with the error 'Too long.'.",
        "DataAnnotation validation failed for members IntRange " +
            "with the error 'Out of range.'.");
}

A validação adiantada (fail fast na inicialização) está sendo considerada para uma versão futura.Eager validation (fail fast at startup) is under consideration for a future release.

Pós-configuração de opçõesOptions post-configuration

Defina a pós-configuração com IPostConfigureOptions<TOptions>.Set post-configuration with IPostConfigureOptions<TOptions>. A pós-configuração é executada depois que toda o configuração de IConfigureOptions<TOptions> é feita:Post-configuration runs after all IConfigureOptions<TOptions> configuration occurs:

services.PostConfigure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

O PostConfigure está disponível para pós-configurar opções nomeadas:PostConfigure is available to post-configure named options:

services.PostConfigure<MyOptions>("named_options_1", myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

Use PostConfigureAll para pós-configurar todas as instâncias de configuração:Use PostConfigureAll to post-configure all configuration instances:

services.PostConfigureAll<MyOptions>(myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

Acessando opções durante a inicializaçãoAccessing options during startup

IOptions<TOptions> e IOptionsMonitor<TOptions> podem ser usados em Startup.Configure, pois os serviços são criados antes da execução do método Configure.IOptions<TOptions> and IOptionsMonitor<TOptions> can be used in Startup.Configure, since services are built before the Configure method executes.

public void Configure(IApplicationBuilder app, IOptionsMonitor<MyOptions> optionsAccessor)
{
    var option1 = optionsAccessor.CurrentValue.Option1;
}

Não use IOptions<TOptions> ou IOptionsMonitor<TOptions> em Startup.ConfigureServices.Don't use IOptions<TOptions> or IOptionsMonitor<TOptions> in Startup.ConfigureServices. Pode haver um estado inconsistente de opções devido à ordenação dos registros de serviço.An inconsistent options state may exist due to the ordering of service registrations.

O padrão de opções usa classes para representar grupos de configurações relacionadas.The options pattern uses classes to represent groups of related settings. Quando as definições de configuração são isoladas por cenário em classes separadas, o aplicativo segue dois princípios importantes de engenharia de software:When configuration settings are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

As opções também fornecem um mecanismo para validar os dados da configuração.Options also provide a mechanism to validate configuration data. Para obter mais configurações, consulte a seção Validação de opções.For more information, see the Options validation section.

Exibir ou baixar código de exemplo (como baixar)View or download sample code (how to download)

Pré-requisitosPrerequisites

Referencie o metapacote Microsoft.AspNetCore.App ou adicione uma referência de pacote ao pacote Microsoft.Extensions.Options.ConfigurationExtensions.Reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Options.ConfigurationExtensions package.

Interfaces de opçõesOptions interfaces

O IOptionsMonitor<TOptions> é usado para recuperar as opções e gerenciar notificações de opções para instâncias de TOptions.IOptionsMonitor<TOptions> is used to retrieve options and manage options notifications for TOptions instances. O IOptionsMonitor<TOptions> dá suporte aos seguintes cenários:IOptionsMonitor<TOptions> supports the following scenarios:

Os cenários de Pós-configuração permitem que você defina ou altere as opções depois de todas as configurações do IConfigureOptions<TOptions> serem feitas.Post-configuration scenarios allow you to set or change options after all IConfigureOptions<TOptions> configuration occurs.

O IOptionsFactory<TOptions> é responsável por criar novas instâncias de opções.IOptionsFactory<TOptions> is responsible for creating new options instances. Ele tem um único método Create.It has a single Create method. A implementação padrão usa todos os IConfigureOptions<TOptions> e IPostConfigureOptions<TOptions> registrados e executa todas as configurações primeiro, seguidas da pós-configuração.The default implementation takes all registered IConfigureOptions<TOptions> and IPostConfigureOptions<TOptions> and runs all the configurations first, followed by the post-configuration. Ela faz distinção entre IConfigureNamedOptions<TOptions> e IConfigureOptions<TOptions> e chama apenas a interface apropriada.It distinguishes between IConfigureNamedOptions<TOptions> and IConfigureOptions<TOptions> and only calls the appropriate interface.

O IOptionsMonitorCache<TOptions> é usado pelo IOptionsMonitor<TOptions> para armazenar em cache as instâncias do TOptions.IOptionsMonitorCache<TOptions> is used by IOptionsMonitor<TOptions> to cache TOptions instances. O IOptionsMonitorCache<TOptions> invalida as instâncias de opções no monitor, de modo que o valor seja recalculado (TryRemove).The IOptionsMonitorCache<TOptions> invalidates options instances in the monitor so that the value is recomputed (TryRemove). Os valores podem ser manualmente inseridos com TryAdd.Values can be manually introduced with TryAdd. O método Clear é usado quando todas as instâncias nomeadas devem ser recriadas sob demanda.The Clear method is used when all named instances should be recreated on demand.

O IOptionsSnapshot<TOptions> é útil em cenários em que as opções devam ser novamente computadas em cada solicitação.IOptionsSnapshot<TOptions> is useful in scenarios where options should be recomputed on every request. Para saber mais, consulte a seção Recarregar dados de configuração com IOptionsSnapshot.For more information, see the Reload configuration data with IOptionsSnapshot section.

O IOptions<TOptions> pode ser usado para dar suporte a opções.IOptions<TOptions> can be used to support options. No entanto, o IOptions<TOptions> não dá suporte a cenários anteriores do IOptionsMonitor<TOptions>.However, IOptions<TOptions> doesn't support the preceding scenarios of IOptionsMonitor<TOptions>. Você pode continuar a usar o IOptions<TOptions> em estruturas e bibliotecas existentes que já usam a interface do IOptions<TOptions> e não exigem os cenários fornecidos pelo IOptionsMonitor<TOptions>.You may continue to use IOptions<TOptions> in existing frameworks and libraries that already use the IOptions<TOptions> interface and don't require the scenarios provided by IOptionsMonitor<TOptions>.

Configuração de opções geraisGeneral options configuration

A configuração de opções gerais é demonstrada no Exemplo #1 no aplicativo de exemplo.General options configuration is demonstrated as Example #1 in the sample app.

Uma classe de opções deve ser não abstrata e com um construtor público sem parâmetros.An options class must be non-abstract with a public parameterless constructor. A classe a seguir, MyOptions, tem duas propriedades, Option1 e Option2.The following class, MyOptions, has two properties, Option1 and Option2. A configuração de valores padrão é opcional, mas o construtor de classe no exemplo a seguir define o valor padrão de Option1.Setting default values is optional, but the class constructor in the following example sets the default value of Option1. Option2 tem um valor padrão definido com a inicialização da propriedade diretamente (Models/MyOptions.cs):Option2 has a default value set by initializing the property directly (Models/MyOptions.cs):

public class MyOptions
{
    public MyOptions()
    {
        // Set default value.
        Option1 = "value1_from_ctor";
    }
    
    public string Option1 { get; set; }
    public int Option2 { get; set; } = 5;
}

A classe MyOptions é adicionada ao contêiner de serviço com Configure e associada à configuração:The MyOptions class is added to the service container with Configure and bound to configuration:

// Example #1: General configuration
// Register the Configuration instance which MyOptions binds against.
services.Configure<MyOptions>(Configuration);

O seguinte modelo de página usa a injeção de dependência de construtor com IOptionsMonitor<TOptions> para acessar as configurações (Pages/Index.cshtml.cs):The following page model uses constructor dependency injection with IOptionsMonitor<TOptions> to access the settings (Pages/Index.cshtml.cs):

private readonly MyOptions _options;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #1: Simple options
var option1 = _options.Option1;
var option2 = _options.Option2;
SimpleOptions = $"option1 = {option1}, option2 = {option2}";

O arquivo appsettings.json de exemplo especifica valores para option1 e option2:The sample's appsettings.json file specifies values for option1 and option2:

{
  "option1": "value1_from_json",
  "option2": -1,
  "subsection": {
    "suboption1": "subvalue1_from_json",
    "suboption2": 200
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Quando o aplicativo é executado, o método OnGet do modelo de página retorna uma cadeia de caracteres que mostra os valores da classe de opção:When the app is run, the page model's OnGet method returns a string showing the option class values:

option1 = value1_from_json, option2 = -1

Observação

Ao usar um ConfigurationBuilder personalizado para carregar opções de configuração de um arquivo de configurações, confirme se o caminho de base está corretamente configurado:When using a custom ConfigurationBuilder to load options configuration from a settings file, confirm that the base path is set correctly:

var configBuilder = new ConfigurationBuilder()
   .SetBasePath(Directory.GetCurrentDirectory())
   .AddJsonFile("appsettings.json", optional: true);
var config = configBuilder.Build();

services.Configure<MyOptions>(config);

Não é necessário configurar o caminho de base explicitamente ao carregar opções de configuração do arquivo de configurações por meio do CreateDefaultBuilder.Explicitly setting the base path isn't required when loading options configuration from the settings file via CreateDefaultBuilder.

Configurar opções simples com um delegadoConfigure simple options with a delegate

A configuração de opções simples com um delegado é demonstrada no Exemplo #2 no aplicativo de exemplo.Configuring simple options with a delegate is demonstrated as Example #2 in the sample app.

Use um delegado para definir valores de opções.Use a delegate to set options values. O aplicativo de exemplo usa a classe MyOptionsWithDelegateConfig (Models/MyOptionsWithDelegateConfig.cs):The sample app uses the MyOptionsWithDelegateConfig class (Models/MyOptionsWithDelegateConfig.cs):

public class MyOptionsWithDelegateConfig
{
    public MyOptionsWithDelegateConfig()
    {
        // Set default value.
        Option1 = "value1_from_ctor";
    }
    
    public string Option1 { get; set; }
    public int Option2 { get; set; } = 5;
}

No código a seguir, um segundo serviço IConfigureOptions<TOptions> é adicionado ao contêiner de serviço.In the following code, a second IConfigureOptions<TOptions> service is added to the service container. Ele usa um delegado para configurar a associação com MyOptionsWithDelegateConfig:It uses a delegate to configure the binding with MyOptionsWithDelegateConfig:

// Example #2: Options bound and configured by a delegate
services.Configure<MyOptionsWithDelegateConfig>(myOptions =>
{
    myOptions.Option1 = "value1_configured_by_delegate";
    myOptions.Option2 = 500;
});

Index.cshtml.cs:Index.cshtml.cs:

private readonly MyOptionsWithDelegateConfig _optionsWithDelegateConfig;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #2: Options configured by delegate
var delegate_config_option1 = _optionsWithDelegateConfig.Option1;
var delegate_config_option2 = _optionsWithDelegateConfig.Option2;
SimpleOptionsWithDelegateConfig = 
    $"delegate_option1 = {delegate_config_option1}, " +
    $"delegate_option2 = {delegate_config_option2}";

Adicione vários provedores de configuração.You can add multiple configuration providers. Os provedores de configuração estão disponíveis nos pacotes do NuGet e são aplicados na ordem em que são registrados.Configuration providers are available from NuGet packages and are applied in the order that they're registered. Para obter mais informações, consulte Configuração no ASP.NET Core.For more information, see Configuração no ASP.NET Core.

Cada chamada à Configure adiciona um serviço IConfigureOptions<TOptions> ao contêiner de serviço.Each call to Configure adds an IConfigureOptions<TOptions> service to the service container. No exemplo anterior, os valores Option1 e Option2 são especificados em appsettings.json, mas os valores Option1 e Option2 são substituídos pelo delegado configurado.In the preceding example, the values of Option1 and Option2 are both specified in appsettings.json, but the values of Option1 and Option2 are overridden by the configured delegate.

Quando mais de um serviço de configuração é habilitado, a última fonte de configuração especificada vence e define o valor de configuração.When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value. Quando o aplicativo é executado, o método OnGet do modelo de página retorna uma cadeia de caracteres que mostra os valores da classe de opção:When the app is run, the page model's OnGet method returns a string showing the option class values:

delegate_option1 = value1_configured_by_delegate, delegate_option2 = 500

Configuração de subopçõesSuboptions configuration

A configuração de subopções é demonstrada no Exemplo #3 no aplicativo de exemplo.Suboptions configuration is demonstrated as Example #3 in the sample app.

Os aplicativos devem criar classes de opções que pertencem a grupos de cenários específicos (classes) no aplicativo.Apps should create options classes that pertain to specific scenario groups (classes) in the app. Partes do aplicativo que exigem valores de configuração devem ter acesso apenas aos valores de configuração usados por elas.Parts of the app that require configuration values should only have access to the configuration values that they use.

Ao associar opções à configuração, cada propriedade no tipo de opções é associada a uma chave de configuração do formato property[:sub-property:].When binding options to configuration, each property in the options type is bound to a configuration key of the form property[:sub-property:]. Por exemplo, a propriedade MyOptions.Option1 é associada à chave Option1, que é lida da propriedade option1 em appsettings.json.For example, the MyOptions.Option1 property is bound to the key Option1, which is read from the option1 property in appsettings.json.

No código a seguir, um terceiro serviço IConfigureOptions<TOptions> é adicionado ao contêiner de serviço.In the following code, a third IConfigureOptions<TOptions> service is added to the service container. Ele associa MySubOptions à seção subsection do arquivo appsettings.json:It binds MySubOptions to the section subsection of the appsettings.json file:

// Example #3: Suboptions
// Bind options using a sub-section of the appsettings.json file.
services.Configure<MySubOptions>(Configuration.GetSection("subsection"));

O método de extensão GetSection exige o pacote NuGet Microsoft.Extensions.Options.ConfigurationExtensions.The GetSection extension method requires the Microsoft.Extensions.Options.ConfigurationExtensions NuGet package. Se o aplicativo usa o metapacote Microsoft.AspNetCore.App (ASP.NET Core 2.1 ou posterior), o pacote é automaticamente incluído.If the app uses the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later), the package is automatically included.

O arquivo appsettings.json de exemplo define um membro subsection com chaves para suboption1 e suboption2:The sample's appsettings.json file defines a subsection member with keys for suboption1 and suboption2:

{
  "option1": "value1_from_json",
  "option2": -1,
  "subsection": {
    "suboption1": "subvalue1_from_json",
    "suboption2": 200
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

A classe MySubOptions define as propriedades SubOption1 e SubOption2, para armazenar os valores de opções (Models/MySubOptions.cs):The MySubOptions class defines properties, SubOption1 and SubOption2, to hold the options values (Models/MySubOptions.cs):

public class MySubOptions
{
    public MySubOptions()
    {
        // Set default values.
        SubOption1 = "value1_from_ctor";
        SubOption2 = 5;
    }
    
    public string SubOption1 { get; set; }
    public int SubOption2 { get; set; }
}

O método OnGet do modelo da página retorna uma cadeia de caracteres com os valores de opções (Pages/Index.cshtml.cs):The page model's OnGet method returns a string with the options values (Pages/Index.cshtml.cs):

private readonly MySubOptions _subOptions;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #3: Suboptions
var subOption1 = _subOptions.SubOption1;
var subOption2 = _subOptions.SubOption2;
SubOptions = $"subOption1 = {subOption1}, subOption2 = {subOption2}";

Quando o aplicativo é executado, o método OnGet retorna uma cadeia de caracteres que mostra os valores da classe de subopção:When the app is run, the OnGet method returns a string showing the suboption class values:

subOption1 = subvalue1_from_json, subOption2 = 200

Opções fornecidas por um modelo de exibição ou com a injeção de exibição diretaOptions provided by a view model or with direct view injection

As opções fornecidas por um modelo de exibição ou com a injeção de exibição direta são demonstradas no Exemplo #4 no aplicativo de exemplo.Options provided by a view model or with direct view injection is demonstrated as Example #4 in the sample app.

As opções podem ser fornecidas em um modelo de exibição ou pela injeção de IOptionsMonitor<TOptions> diretamente em uma exibição (Pages/Index.cshtml.cs):Options can be supplied in a view model or by injecting IOptionsMonitor<TOptions> directly into a view (Pages/Index.cshtml.cs):

private readonly MyOptions _options;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #4: Bind options directly to the page
MyOptions = _options;

O aplicativo de exemplo mostra como injetar IOptionsMonitor<MyOptions> com uma diretiva @inject:The sample app shows how to inject IOptionsMonitor<MyOptions> with an @inject directive:

@page
@model IndexModel
@using Microsoft.Extensions.Options
@inject IOptionsMonitor<MyOptions> OptionsAccessor
@{
    ViewData["Title"] = "Options Sample";
}

<h1>@ViewData["Title"]</h1>

Quando o aplicativo é executado, os valores de opções são mostrados na página renderizada:When the app is run, the options values are shown in the rendered page:

Os valores de opções Option1: value1_from_json e Option2: -1 são carregados do modelo e pela injeção na exibição.

Recarregar dados de configuração com IOptionsSnapshotReload configuration data with IOptionsSnapshot

O recarregamento de dados de configuração com IOptionsSnapshot<TOptions> é demonstrado no Exemplo #5 no aplicativo de exemplo.Reloading configuration data with IOptionsSnapshot<TOptions> is demonstrated in Example #5 in the sample app.

O IOptionsSnapshot<TOptions> dá suporte a opções de recarregamento com sobrecarga mínima de processamento.IOptionsSnapshot<TOptions> supports reloading options with minimal processing overhead.

As opções são calculadas uma vez por solicitação, quando acessadas e armazenadas em cache durante o tempo de vida da solicitação.Options are computed once per request when accessed and cached for the lifetime of the request.

O exemplo a seguir demonstra como um novo IOptionsSnapshot<TOptions> é criado após a alteração de appsettings.json (Pages/Index.cshtml.cs).The following example demonstrates how a new IOptionsSnapshot<TOptions> is created after appsettings.json changes (Pages/Index.cshtml.cs). Várias solicitações ao servidor retornam valores de constante fornecidos pelo arquivo appsettings.json, até que o arquivo seja alterado e a configuração seja recarregada.Multiple requests to the server return constant values provided by the appsettings.json file until the file is changed and configuration reloads.

private readonly MyOptions _snapshotOptions;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #5: Snapshot options
var snapshotOption1 = _snapshotOptions.Option1;
var snapshotOption2 = _snapshotOptions.Option2;
SnapshotOptions = 
    $"snapshot option1 = {snapshotOption1}, " +
    $"snapshot option2 = {snapshotOption2}";

A seguinte imagem mostra is valores option1 e option2 iniciais carregados do arquivo appsettings.json:The following image shows the initial option1 and option2 values loaded from the appsettings.json file:

snapshot option1 = value1_from_json, snapshot option2 = -1

Altere os valores no arquivo appsettings.json para value1_from_json UPDATED e 200.Change the values in the appsettings.json file to value1_from_json UPDATED and 200. Salve o arquivo appsettings.json.Save the appsettings.json file. Atualize o navegador para ver se os valores de opções foram atualizados:Refresh the browser to see that the options values are updated:

snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200

Suporte de opções nomeadas com IConfigureNamedOptionsNamed options support with IConfigureNamedOptions

O suporte de opções nomeadas com IConfigureNamedOptions<TOptions> é demonstrado como no Exemplo #6 no aplicativo de exemplo.Named options support with IConfigureNamedOptions<TOptions> is demonstrated as Example #6 in the sample app.

O suporte de opções nomeadas permite que o aplicativo faça a distinção entre as configurações de opções nomeadas.Named options support allows the app to distinguish between named options configurations. No aplicativo de exemplo, as opções nomeadas são declaradas com OptionsServiceCollectionExtensions.Configure que chama o método de extensão ConfigureNamedOptions<TOptions>.Configure:In the sample app, named options are declared with OptionsServiceCollectionExtensions.Configure, which calls the ConfigureNamedOptions<TOptions>.Configure extension method:

// Example #6: Named options (named_options_1)
// Register the ConfigurationBuilder instance which MyOptions binds against.
// Specify that the options loaded from configuration are named
// "named_options_1".
services.Configure<MyOptions>("named_options_1", Configuration);

// Example #6: Named options (named_options_2)
// Specify that the options loaded from the MyOptions class are named
// "named_options_2".
// Use a delegate to configure option values.
services.Configure<MyOptions>("named_options_2", myOptions =>
{
    myOptions.Option1 = "named_options_2_value1_from_action";
});

O aplicativo de exemplo acessa as opções nomeadas com Get (Pages/Index.cshtml.cs):The sample app accesses the named options with Get (Pages/Index.cshtml.cs):

private readonly MyOptions _named_options_1;
private readonly MyOptions _named_options_2;
public IndexModel(
    IOptionsMonitor<MyOptions> optionsAccessor, 
    IOptionsMonitor<MyOptionsWithDelegateConfig> optionsAccessorWithDelegateConfig, 
    IOptionsMonitor<MySubOptions> subOptionsAccessor, 
    IOptionsSnapshot<MyOptions> snapshotOptionsAccessor, 
    IOptionsSnapshot<MyOptions> namedOptionsAccessor)
{
    _options = optionsAccessor.CurrentValue;
    _optionsWithDelegateConfig = optionsAccessorWithDelegateConfig.CurrentValue;
    _subOptions = subOptionsAccessor.CurrentValue;
    _snapshotOptions = snapshotOptionsAccessor.Value;
    _named_options_1 = namedOptionsAccessor.Get("named_options_1");
    _named_options_2 = namedOptionsAccessor.Get("named_options_2");
}
// Example #6: Named options
var named_options_1 = 
    $"named_options_1: option1 = {_named_options_1.Option1}, " +
    $"option2 = {_named_options_1.Option2}";
var named_options_2 = 
    $"named_options_2: option1 = {_named_options_2.Option1}, " +
    $"option2 = {_named_options_2.Option2}";
NamedOptions = $"{named_options_1} {named_options_2}";

Executando o aplicativo de exemplo, as opções nomeadas são retornadas:Running the sample app, the named options are returned:

named_options_1: option1 = value1_from_json, option2 = -1
named_options_2: option1 = named_options_2_value1_from_action, option2 = 5

Os valores named_options_1 são fornecidos pela configuração, que são carregados do arquivo appsettings.json.named_options_1 values are provided from configuration, which are loaded from the appsettings.json file. Os valores named_options_2 são fornecidos pelo:named_options_2 values are provided by:

  • Delegado named_options_2 em ConfigureServices para Option1.The named_options_2 delegate in ConfigureServices for Option1.
  • Valor padrão para Option2 fornecido pela classe MyOptions.The default value for Option2 provided by the MyOptions class.

Configurar todas as opções com o método ConfigureAllConfigure all options with the ConfigureAll method

Configure todas as instâncias de opções com o método ConfigureAll.Configure all options instances with the ConfigureAll method. O código a seguir configura Option1 para todas as instâncias de configuração com um valor comum.The following code configures Option1 for all configuration instances with a common value. Adicione o seguinte código manualmente ao método Startup.ConfigureServices:Add the following code manually to the Startup.ConfigureServices method:

services.ConfigureAll<MyOptions>(myOptions => 
{
    myOptions.Option1 = "ConfigureAll replacement value";
});

A execução do aplicativo de exemplo após a adição do código produz o seguinte resultado:Running the sample app after adding the code produces the following result:

named_options_1: option1 = ConfigureAll replacement value, option2 = -1
named_options_2: option1 = ConfigureAll replacement value, option2 = 5

Observação

Todas as opções são instâncias nomeadas.All options are named instances. As instâncias IConfigureOptions<TOptions> existentes são tratadas como sendo direcionadas à instância Options.DefaultName, que é string.Empty.Existing IConfigureOptions<TOptions> instances are treated as targeting the Options.DefaultName instance, which is string.Empty. IConfigureNamedOptions<TOptions> também implementa IConfigureOptions<TOptions>.IConfigureNamedOptions<TOptions> also implements IConfigureOptions<TOptions>. A implementação padrão de IOptionsFactory<TOptions> tem lógica para usar cada um de forma adequada.The default implementation of the IOptionsFactory<TOptions> has logic to use each appropriately. A opção nomeada null é usada para direcionar todas as instâncias nomeadas, em vez de uma instância nomeada específica (ConfigureAll e PostConfigureAll usam essa convenção).The null named option is used to target all of the named instances instead of a specific named instance (ConfigureAll and PostConfigureAll use this convention).

API OptionsBuilderOptionsBuilder API

OptionsBuilder<TOptions> é usada para configurar instâncias TOptions.OptionsBuilder<TOptions> is used to configure TOptions instances. OptionsBuilder simplifica a criação de opções nomeadas, pois é apenas um único parâmetro para a chamada AddOptions<TOptions>(string optionsName) inicial, em vez de aparecer em todas as chamadas subsequentes.OptionsBuilder streamlines creating named options as it's only a single parameter to the initial AddOptions<TOptions>(string optionsName) call instead of appearing in all of the subsequent calls. A validação de opções e as sobrecargas ConfigureOptions que aceitam dependências de serviço só estão disponíveis por meio de OptionsBuilder.Options validation and the ConfigureOptions overloads that accept service dependencies are only available via OptionsBuilder.

// Options.DefaultName = "" is used.
services.AddOptions<MyOptions>().Configure(o => o.Property = "default");

services.AddOptions<MyOptions>("optionalName")
    .Configure(o => o.Property = "named");

Usar os serviços de injeção de dependência para configurar as opçõesUse DI services to configure options

Você pode acessar outros serviços de injeção de dependência ao configurar as opções de duas maneiras:You can access other services from dependency injection while configuring options in two ways:

É recomendável transmitir um delegado de configuração para Configurar, já que a criação de um serviço é algo mais complexo.We recommend passing a configuration delegate to Configure, since creating a service is more complex. Criar seu próprio tipo é equivalente ao que a estrutura faz para você quando você usa Configure.Creating your own type is equivalent to what the framework does for you when you use Configure. Chamar Configure registra um genérico transitório IConfigureNamedOptions<TOptions>, que tem um construtor que aceita os tipos de serviço genérico especificados.Calling Configure registers a transient generic IConfigureNamedOptions<TOptions>, which has a constructor that accepts the generic service types specified.

Pós-configuração de opçõesOptions post-configuration

Defina a pós-configuração com IPostConfigureOptions<TOptions>.Set post-configuration with IPostConfigureOptions<TOptions>. A pós-configuração é executada depois que toda o configuração de IConfigureOptions<TOptions> é feita:Post-configuration runs after all IConfigureOptions<TOptions> configuration occurs:

services.PostConfigure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

O PostConfigure está disponível para pós-configurar opções nomeadas:PostConfigure is available to post-configure named options:

services.PostConfigure<MyOptions>("named_options_1", myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

Use PostConfigureAll para pós-configurar todas as instâncias de configuração:Use PostConfigureAll to post-configure all configuration instances:

services.PostConfigureAll<MyOptions>(myOptions =>
{
    myOptions.Option1 = "post_configured_option1_value";
});

Acessando opções durante a inicializaçãoAccessing options during startup

IOptions<TOptions> e IOptionsMonitor<TOptions> podem ser usados em Startup.Configure, pois os serviços são criados antes da execução do método Configure.IOptions<TOptions> and IOptionsMonitor<TOptions> can be used in Startup.Configure, since services are built before the Configure method executes.

public void Configure(IApplicationBuilder app, IOptionsMonitor<MyOptions> optionsAccessor)
{
    var option1 = optionsAccessor.CurrentValue.Option1;
}

Não use IOptions<TOptions> ou IOptionsMonitor<TOptions> em Startup.ConfigureServices.Don't use IOptions<TOptions> or IOptionsMonitor<TOptions> in Startup.ConfigureServices. Pode haver um estado inconsistente de opções devido à ordenação dos registros de serviço.An inconsistent options state may exist due to the ordering of service registrations.

Recursos adicionaisAdditional resources