Modello di opzioni in ASP.NET CoreOptions pattern in ASP.NET Core

Di Luke LathamBy Luke Latham

Il modello di opzioni usa le classi per rappresentare i gruppi di impostazioni correlate.The options pattern uses classes to represent groups of related settings. Quando le impostazioni di configurazione vengono isolate in base allo scenario in classi separate, l'app aderisce a due importanti principi di progettazione del software:When configuration settings are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

Le opzioni offrono anche un meccanismo per convalidare i dati di configurazione.Options also provide a mechanism to validate configuration data. Per altre informazioni, vedere la sezione Opzioni di convalida.For more information, see the Options validation section.

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

PacchettoPackage

Al pacchetto Microsoft. Extensions. Options. ConfigurationExtensions viene fatto riferimento in modo implicito nelle app ASP.NET Core.The Microsoft.Extensions.Options.ConfigurationExtensions package is implicitly referenced in ASP.NET Core apps.

Interfacce per le opzioniOptions interfaces

IOptionsMonitor<TOptions> consente di recuperare le opzioni e gestire le notifiche di opzioni per le istanze TOptions.IOptionsMonitor<TOptions> is used to retrieve options and manage options notifications for TOptions instances. IOptionsMonitor<TOptions> supporta gli scenari seguenti:IOptionsMonitor<TOptions> supports the following scenarios:

Gli scenari di post-configurazione consentono di impostare o modificare le opzioni dopo la configurazione di tutte le IConfigureOptions<TOptions>.Post-configuration scenarios allow you to set or change options after all IConfigureOptions<TOptions> configuration occurs.

IOptionsFactory<TOptions> è responsabile della creazione di nuove istanze di opzioni.IOptionsFactory<TOptions> is responsible for creating new options instances. Include un singolo metodo Create.It has a single Create method. L'implementazione predefinita accetta tutte le interfacce IConfigureOptions<TOptions> e IPostConfigureOptions<TOptions> registrate ed esegue tutte le configurazioni, seguite dalla post-configurazione.The default implementation takes all registered IConfigureOptions<TOptions> and IPostConfigureOptions<TOptions> and runs all the configurations first, followed by the post-configuration. Fa distinzione tra IConfigureNamedOptions<TOptions> e IConfigureOptions<TOptions> e chiama solo l'interfaccia appropriata.It distinguishes between IConfigureNamedOptions<TOptions> and IConfigureOptions<TOptions> and only calls the appropriate interface.

IOptionsMonitorCache<TOptions> viene usata da IOptionsMonitor<TOptions> per memorizzare nella cache le istanze di TOptions.IOptionsMonitorCache<TOptions> is used by IOptionsMonitor<TOptions> to cache TOptions instances. IOptionsMonitorCache<TOptions> invalida le istanze delle opzioni nel monitoraggio in modo che il valore venga ricalcolato (TryRemove).The IOptionsMonitorCache<TOptions> invalidates options instances in the monitor so that the value is recomputed (TryRemove). I valori possono essere introdotti manualmente con TryAdd.Values can be manually introduced with TryAdd. Il metodo Clear viene usato quando tutte le istanze denominate devono essere ricreate su richiesta.The Clear method is used when all named instances should be recreated on demand.

IOptionsSnapshot<TOptions> è utile negli scenari in cui le opzioni devono essere ricalcolate a ogni richiesta.IOptionsSnapshot<TOptions> is useful in scenarios where options should be recomputed on every request. Per altre informazioni, vedere la sezione Ricaricare i dati di configurazione con IOptionsSnapshot.For more information, see the Reload configuration data with IOptionsSnapshot section.

IOptions<TOptions> può essere usata a supporto delle opzioni.IOptions<TOptions> can be used to support options. Tuttavia IOptions<TOptions> non supporta gli scenari precedenti di IOptionsMonitor<TOptions>.However, IOptions<TOptions> doesn't support the preceding scenarios of IOptionsMonitor<TOptions>. È possibile continuare a usare IOptions<TOptions> in framework e librerie esistenti che già usano l'interfaccia IOptions<TOptions> e non richiedono gli scenari forniti da 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>.

Configurazione delle opzioni generaliGeneral options configuration

La configurazione delle opzioni generali è illustrata nell'Esempio #1 nell'app di esempio.General options configuration is demonstrated as Example #1 in the sample app.

Una classe di opzioni deve essere non astratta con un costruttore pubblico senza parametri.An options class must be non-abstract with a public parameterless constructor. La classe seguente, MyOptions, ha due proprietà, Option1 e Option2.The following class, MyOptions, has two properties, Option1 and Option2. Sebbene l'impostazione dei valori predefiniti sia facoltativa, il costruttore della classe nell'esempio seguente imposta il valore predefinito di Option1.Setting default values is optional, but the class constructor in the following example sets the default value of Option1. Option2 ha un valore impostato tramite l'inizializzazione diretta della proprietà (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;
}

La classe MyOptions viene aggiunta al contenitore di servizi con Configure e associata alla configurazione: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);

Il modello di pagina seguente usa l'inserimento delle dipendenze del costruttore con IOptionsMonitor<TOptions> per accedere alle impostazioni (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}";

Il file appsettings.json dell'esempio specifica i valori di 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 viene eseguita l'app, il metodo OnGet del modello di pagina restituisce una stringa che mostra i valori delle classi delle opzioni: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

Nota

Se si usa un ConfigurationBuilder personalizzato per caricare la configurazione delle opzioni da un file di impostazioni, verificare che il percorso base sia impostato correttamente: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);

L'impostazione esplicita del percorso base non è necessaria se si carica la configurazione delle opzioni dal file di impostazioni tramite CreateDefaultBuilder.Explicitly setting the base path isn't required when loading options configuration from the settings file via CreateDefaultBuilder.

Configurare opzioni semplici con un delegatoConfigure simple options with a delegate

La configurazione di opzioni semplici con un delegato è illustrata nell'Esempio #2 nell'app di esempio.Configuring simple options with a delegate is demonstrated as Example #2 in the sample app.

Usare un delegato per impostare i valori delle opzioni.Use a delegate to set options values. L'app di esempio usa la 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;
}

Nel codice seguente viene aggiunto un secondo servizio IConfigureOptions<TOptions> al contenitore di servizi.In the following code, a second IConfigureOptions<TOptions> service is added to the service container. Viene usato un delegato per configurare l'associazione a 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}";

È possibile aggiungere più provider di configurazione.You can add multiple configuration providers. I provider di configurazione sono disponibili dai pacchetti NuGet e vengono applicati nell'ordine in cui sono registrati.Configuration providers are available from NuGet packages and are applied in the order that they're registered. Per ulteriori informazioni, vedere Configurazione in ASP.NET Core.For more information, see Configurazione in ASP.NET Core.

Ogni chiamata a Configure aggiunge un servizio IConfigureOptions<TOptions> al contenitore di servizi.Each call to Configure adds an IConfigureOptions<TOptions> service to the service container. Nell'esempio precedente i valori di Option1 e Option2 sono entrambi specificati in appsettings.json, mentre i valori di Option1 e Option2 sono sottoposti a override dal delegato configurato.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 sono abilitati più servizi di configurazione, l'origine di configurazione più recente specificata ha priorità e imposta il valore di configurazione.When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value. Quando viene eseguita l'app, il metodo OnGet del modello di pagina restituisce una stringa che mostra i valori delle classi delle opzioni: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

Configurazione delle opzioni secondarieSuboptions configuration

La configurazione delle opzioni secondarie è illustrata nell'Esempio #3 nell'app di esempio.Suboptions configuration is demonstrated as Example #3 in the sample app.

Le app devono creare classi di opzioni che riguardano gruppi di scenari (classi) specifici nell'app.Apps should create options classes that pertain to specific scenario groups (classes) in the app. Le parti dell'app che richiedono valori di configurazione devono avere accesso solo ai valori di configurazione necessari.Parts of the app that require configuration values should only have access to the configuration values that they use.

Durante l'associazione delle opzioni alla configurazione, ogni proprietà del tipo di opzioni viene associata a una chiave di configurazione con 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:]. Ad esempio, la proprietà MyOptions.Option1 viene associata alla chiave Option1, che viene letta dalla proprietà option1 in appsettings.json.For example, the MyOptions.Option1 property is bound to the key Option1, which is read from the option1 property in appsettings.json.

Nel codice seguente viene aggiunto un terzo servizio IConfigureOptions<TOptions> al contenitore di servizi.In the following code, a third IConfigureOptions<TOptions> service is added to the service container. MySubOptions viene associato alla sezione subsection del file 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"));

Il metodo di estensione GetSection richiede il pacchetto NuGet Microsoft.Extensions.Options.ConfigurationExtensions.The GetSection extension method requires the Microsoft.Extensions.Options.ConfigurationExtensions NuGet package. in ASP.NET Core app viene fatto riferimento in modo implicito a Microsoft.Extensions.Options.ConfigurationExtensions.Microsoft.Extensions.Options.ConfigurationExtensions is implicitly referenced in ASP.NET Core apps.

Il file appsettings.json dell'esempio definisce un membro subsection con chiavi per 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": "*"
}

La classe MySubOptions definisce le proprietà SubOption1 e SubOption2 per contenere i valori delle opzioni (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; }
}

Il metodo OnGet del modello di pagina restituisce una stringa con i valori delle opzioni (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 viene eseguita l'app, il metodo OnGet restituisce una stringa che mostra i valori delle classi delle opzioni secondarie:When the app is run, the OnGet method returns a string showing the suboption class values:

subOption1 = subvalue1_from_json, subOption2 = 200

Opzioni fornite da un modello di visualizzazione o con l'inserimento diretto della visualizzazioneOptions provided by a view model or with direct view injection

Le opzioni fornite da un modello di visualizzazione o con l'inserimento diretto della visualizzazione sono illustrate nell'Esempio #4 nell'app di esempio.Options provided by a view model or with direct view injection is demonstrated as Example #4 in the sample app.

Le opzioni possono essere rese disponibili in un modello di visualizzazione oppure inserendo IOptionsMonitor<TOptions> direttamente in una visualizzazione (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;

L'app di esempio mostra come inserire IOptionsMonitor<MyOptions> con una direttiva @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 l'app viene eseguita, i valori delle opzioni sono visibili nella pagina di cui è stato eseguito il rendering:When the app is run, the options values are shown in the rendered page:

I valori delle opzioni Option1: value1_from_json e Option2: -1 vengono caricati dal modello e tramite inserimento nella visualizzazione.

Ricaricare i dati di configurazione con IOptionsSnapshotReload configuration data with IOptionsSnapshot

Il ricaricamento dei dati di configurazione con IOptionsSnapshot<TOptions> è illustrato nell'Esempio #5 nell'app di esempio.Reloading configuration data with IOptionsSnapshot<TOptions> is demonstrated in Example #5 in the sample app.

IOptionsSnapshot<TOptions> supporta il ricaricamento delle opzioni con un overhead di elaborazione minimo.IOptionsSnapshot<TOptions> supports reloading options with minimal processing overhead.

Le opzioni vengono calcolate una volta per richiesta quando viene eseguito l'accesso e la memorizzazione nella cache per la durata della richiesta.Options are computed once per request when accessed and cached for the lifetime of the request.

L'esempio seguente illustra la creazione di un nuovo IOptionsSnapshot<TOptions> dopo le modifiche ad 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). Più richieste al server restituiscono valori costanti forniti dal file appsettings.json fino a quando il file non viene modificato e la configurazione non viene ricaricata.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}";

L'immagine seguente illustra i valori iniziali option1 e option2 caricati dal file 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

Modificare i valori nel file appsettings.json in value1_from_json UPDATED e 200.Change the values in the appsettings.json file to value1_from_json UPDATED and 200. Salvare il file appsettings.json.Save the appsettings.json file. Aggiornare il browser per visualizzare i valori delle opzioni aggiornati:Refresh the browser to see that the options values are updated:

snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200

Supporto delle opzioni denominate con IConfigureNamedOptionsNamed options support with IConfigureNamedOptions

Il supporto delle opzioni denominate con IConfigureNamedOptions<TOptions> è illustrato nell'Esempio #6 nell'app di esempio.Named options support with IConfigureNamedOptions<TOptions> is demonstrated as Example #6 in the sample app.

Il supporto delle opzioni denominate consente all'app di distinguere le configurazioni delle opzioni denominate.Named options support allows the app to distinguish between named options configurations. Nell'app di esempio le opzioni denominate vengono dichiarate con OptionsServiceCollectionExtensions.Configure, che chiama il metodo di estensione 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";
});

L'app di esempio accede alle opzioni denominate con 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}";

Eseguendo l'app di esempio, vengono restituite le opzioni denominate: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

I valori named_options_1 vengono specificati dalla configurazione, caricata dal file appsettings.json.named_options_1 values are provided from configuration, which are loaded from the appsettings.json file. I valori named_options_2 sono specificati da:named_options_2 values are provided by:

  • Delegato named_options_2 in ConfigureServices per Option1.The named_options_2 delegate in ConfigureServices for Option1.
  • Valore predefinito per Option2 specificato dalla classe MyOptions.The default value for Option2 provided by the MyOptions class.

Configurare tutte le opzioni con il metodo ConfigureAllConfigure all options with the ConfigureAll method

Configurare tutte le istanze delle opzioni con il metodo ConfigureAll.Configure all options instances with the ConfigureAll method. Il codice seguente configura Option1 per tutte le istanze di configurazione con un valore comune.The following code configures Option1 for all configuration instances with a common value. Aggiungere manualmente il codice seguente al metodo Startup.ConfigureServices:Add the following code manually to the Startup.ConfigureServices method:

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

L'esecuzione dell'app di esempio dopo l'aggiunta del codice produce il risultato seguente: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

Nota

Tutte le opzioni sono istanze denominate.All options are named instances. Le istanze di IConfigureOptions<TOptions> esistenti sono trattate come se fossero indirizzate all'istanza di Options.DefaultName, ovvero string.Empty.Existing IConfigureOptions<TOptions> instances are treated as targeting the Options.DefaultName instance, which is string.Empty. IConfigureNamedOptions<TOptions> implementa anche IConfigureOptions<TOptions>.IConfigureNamedOptions<TOptions> also implements IConfigureOptions<TOptions>. L'implementazione predefinita di IOptionsFactory<TOptions> include la logica per usarle in modo appropriato.The default implementation of the IOptionsFactory<TOptions> has logic to use each appropriately. L'opzione denominata null viene usata per avere come destinazione tutte le istanze denominate anziché un'istanza specifica denominata (questa convenzione è usata da ConfigureAll e PostConfigureAll).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> viene usata per configurare le istanze di TOptions.OptionsBuilder<TOptions> is used to configure TOptions instances. OptionsBuilder semplifica la creazione di opzioni denominate perché è costituita da un singolo parametro nella chiamata iniziale ad AddOptions<TOptions>(string optionsName) invece di essere visualizzata in tutte le chiamate successive.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. La convalida delle opzioni e gli overload ConfigureOptions che accettano le dipendenze dei servizi sono disponibili solo tramite 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");

Usare i servizi di inserimento delle dipendenze per configurare le opzioniUse DI services to configure options

È possibile accedere ad altri servizi dall'inserimento delle dipendenze durante la configurazione delle opzioni in due modi:You can access other services from dependency injection while configuring options in two ways:

È consigliabile passare un delegato di configurazione a Configure perché la creazione di un servizio è più complessa.We recommend passing a configuration delegate to Configure, since creating a service is more complex. La creazione di un tipo personalizzato equivale alle operazioni che il framework esegue automaticamente quando si usa Configure.Creating your own type is equivalent to what the framework does for you when you use Configure. La chiamata a Configure registra un'interfaccia IConfigureNamedOptions<TOptions> generica temporanea, che ha un costruttore che accetta i tipi di servizi generici specificati.Calling Configure registers a transient generic IConfigureNamedOptions<TOptions>, which has a constructor that accepts the generic service types specified.

Convalida delle opzioniOptions validation

La convalida le opzioni consente di convalidare le opzioni quando vengono configurate.Options validation allows you to validate options when options are configured. Chiamare Validate con un metodo di convalida che restituisce true se le opzioni sono valide e false se non sono valide: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"
}

L'esempio precedente imposta l'istanza di opzioni denominata su optionalOptionsName.The preceding example sets the named options instance to optionalOptionsName. L'istanza di opzioni predefinita è Options.DefaultName.The default options instance is Options.DefaultName.

La convalida viene eseguita quando viene creata l'istanza di opzioni.Validation runs when the options instance is created. L'istanza di opzioni supera sicuramente la convalida al primo accesso.Your options instance is guaranteed to pass validation the first time it's accessed.

Importante

La convalida delle opzioni non protegge da eventuali modifiche dopo la configurazione e la convalida iniziali delle opzioni.Options validation doesn't guard against options modifications after the options are initially configured and validated.

Il metodo Validate accetta Func<TOptions, bool>.The Validate method accepts a Func<TOptions, bool>. Per personalizzare completamente la convalida, implementare IValidateOptions<TOptions>, che consente:To fully customize validation, implement IValidateOptions<TOptions>, which allows:

  • La convalida di più tipi di opzioni: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>Validation of multiple options types: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>
  • La convalida che dipende da un altro tipo di opzione: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)Validation that depends on another option type: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)

IValidateOptions convalida:IValidateOptions validates:

  • Un'istanza di opzioni denominata specifica.A specific named options instance.
  • Tutte le opzioni quando name è null.All options when name is null.

Restituire ValidateOptionsResult dall'implementazione dell'interfaccia:Return a ValidateOptionsResult from your implementation of the interface:

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

La convalida basata sull'annotazione dei dati è disponibile dal pacchetto Microsoft.Extensions.Options.DataAnnotations chiamando il metodo ValidateDataAnnotations su OptionsBuilder<TOptions>.Data Annotation-based validation is available from the Microsoft.Extensions.Options.DataAnnotations package by calling the ValidateDataAnnotations method on OptionsBuilder<TOptions>. in ASP.NET Core app viene fatto riferimento in modo implicito a Microsoft.Extensions.Options.DataAnnotations.Microsoft.Extensions.Options.DataAnnotations is implicitly referenced in ASP.NET Core apps.

using System.ComponentModel.DataAnnotations;
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>>().CurrentValue);
    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.'.");
}

La convalida eager (fallimento e risposta immediata agli errori all'avvio) è pianificata per una versione futura.Eager validation (fail fast at startup) is under consideration for a future release.

Post-configurazione delle opzioniOptions post-configuration

Impostare la post-configurazione con IPostConfigureOptions<TOptions>.Set post-configuration with IPostConfigureOptions<TOptions>. La post-configurazione viene eseguita dopo il completamento della configurazione di tutte le IConfigureOptions<TOptions>:Post-configuration runs after all IConfigureOptions<TOptions> configuration occurs:

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

PostConfigure è disponibile per la post-configurazione delle opzioni denominate:PostConfigure is available to post-configure named options:

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

Usare PostConfigureAll per la post-configurazione di tutte le istanze di configurazione:Use PostConfigureAll to post-configure all configuration instances:

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

Accesso alle opzioni durante l'avvioAccessing options during startup

IOptions<TOptions> e IOptionsMonitor<TOptions> possono essere usate in Startup.Configure, perché i servizi vengono compilati prima dell'esecuzione del metodo 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;
}

Non usare IOptions<TOptions> oppure IOptionsMonitor<TOptions> in Startup.ConfigureServices.Don't use IOptions<TOptions> or IOptionsMonitor<TOptions> in Startup.ConfigureServices. Le opzioni potrebbero avere uno stato incoerente a causa dell'ordinamento delle registrazioni dei servizi.An inconsistent options state may exist due to the ordering of service registrations.

Il modello di opzioni usa le classi per rappresentare i gruppi di impostazioni correlate.The options pattern uses classes to represent groups of related settings. Quando le impostazioni di configurazione vengono isolate in base allo scenario in classi separate, l'app aderisce a due importanti principi di progettazione del software:When configuration settings are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

Le opzioni offrono anche un meccanismo per convalidare i dati di configurazione.Options also provide a mechanism to validate configuration data. Per altre informazioni, vedere la sezione Opzioni di convalida.For more information, see the Options validation section.

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

PrerequisitesPrerequisites

Fare riferimento al metapacchetto Microsoft.AspNetCore.App oppure aggiungere un riferimento al pacchetto Microsoft.Extensions.Options.ConfigurationExtensions.Reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Options.ConfigurationExtensions package.

Interfacce per le opzioniOptions interfaces

IOptionsMonitor<TOptions> consente di recuperare le opzioni e gestire le notifiche di opzioni per le istanze TOptions.IOptionsMonitor<TOptions> is used to retrieve options and manage options notifications for TOptions instances. IOptionsMonitor<TOptions> supporta gli scenari seguenti:IOptionsMonitor<TOptions> supports the following scenarios:

Gli scenari di post-configurazione consentono di impostare o modificare le opzioni dopo la configurazione di tutte le IConfigureOptions<TOptions>.Post-configuration scenarios allow you to set or change options after all IConfigureOptions<TOptions> configuration occurs.

IOptionsFactory<TOptions> è responsabile della creazione di nuove istanze di opzioni.IOptionsFactory<TOptions> is responsible for creating new options instances. Include un singolo metodo Create.It has a single Create method. L'implementazione predefinita accetta tutte le interfacce IConfigureOptions<TOptions> e IPostConfigureOptions<TOptions> registrate ed esegue tutte le configurazioni, seguite dalla post-configurazione.The default implementation takes all registered IConfigureOptions<TOptions> and IPostConfigureOptions<TOptions> and runs all the configurations first, followed by the post-configuration. Fa distinzione tra IConfigureNamedOptions<TOptions> e IConfigureOptions<TOptions> e chiama solo l'interfaccia appropriata.It distinguishes between IConfigureNamedOptions<TOptions> and IConfigureOptions<TOptions> and only calls the appropriate interface.

IOptionsMonitorCache<TOptions> viene usata da IOptionsMonitor<TOptions> per memorizzare nella cache le istanze di TOptions.IOptionsMonitorCache<TOptions> is used by IOptionsMonitor<TOptions> to cache TOptions instances. IOptionsMonitorCache<TOptions> invalida le istanze delle opzioni nel monitoraggio in modo che il valore venga ricalcolato (TryRemove).The IOptionsMonitorCache<TOptions> invalidates options instances in the monitor so that the value is recomputed (TryRemove). I valori possono essere introdotti manualmente con TryAdd.Values can be manually introduced with TryAdd. Il metodo Clear viene usato quando tutte le istanze denominate devono essere ricreate su richiesta.The Clear method is used when all named instances should be recreated on demand.

IOptionsSnapshot<TOptions> è utile negli scenari in cui le opzioni devono essere ricalcolate a ogni richiesta.IOptionsSnapshot<TOptions> is useful in scenarios where options should be recomputed on every request. Per altre informazioni, vedere la sezione Ricaricare i dati di configurazione con IOptionsSnapshot.For more information, see the Reload configuration data with IOptionsSnapshot section.

IOptions<TOptions> può essere usata a supporto delle opzioni.IOptions<TOptions> can be used to support options. Tuttavia IOptions<TOptions> non supporta gli scenari precedenti di IOptionsMonitor<TOptions>.However, IOptions<TOptions> doesn't support the preceding scenarios of IOptionsMonitor<TOptions>. È possibile continuare a usare IOptions<TOptions> in framework e librerie esistenti che già usano l'interfaccia IOptions<TOptions> e non richiedono gli scenari forniti da 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>.

Configurazione delle opzioni generaliGeneral options configuration

La configurazione delle opzioni generali è illustrata nell'Esempio #1 nell'app di esempio.General options configuration is demonstrated as Example #1 in the sample app.

Una classe di opzioni deve essere non astratta con un costruttore pubblico senza parametri.An options class must be non-abstract with a public parameterless constructor. La classe seguente, MyOptions, ha due proprietà, Option1 e Option2.The following class, MyOptions, has two properties, Option1 and Option2. Sebbene l'impostazione dei valori predefiniti sia facoltativa, il costruttore della classe nell'esempio seguente imposta il valore predefinito di Option1.Setting default values is optional, but the class constructor in the following example sets the default value of Option1. Option2 ha un valore impostato tramite l'inizializzazione diretta della proprietà (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;
}

La classe MyOptions viene aggiunta al contenitore di servizi con Configure e associata alla configurazione: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);

Il modello di pagina seguente usa l'inserimento delle dipendenze del costruttore con IOptionsMonitor<TOptions> per accedere alle impostazioni (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}";

Il file appsettings.json dell'esempio specifica i valori di 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 viene eseguita l'app, il metodo OnGet del modello di pagina restituisce una stringa che mostra i valori delle classi delle opzioni: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

Nota

Se si usa un ConfigurationBuilder personalizzato per caricare la configurazione delle opzioni da un file di impostazioni, verificare che il percorso base sia impostato correttamente: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);

L'impostazione esplicita del percorso base non è necessaria se si carica la configurazione delle opzioni dal file di impostazioni tramite CreateDefaultBuilder.Explicitly setting the base path isn't required when loading options configuration from the settings file via CreateDefaultBuilder.

Configurare opzioni semplici con un delegatoConfigure simple options with a delegate

La configurazione di opzioni semplici con un delegato è illustrata nell'Esempio #2 nell'app di esempio.Configuring simple options with a delegate is demonstrated as Example #2 in the sample app.

Usare un delegato per impostare i valori delle opzioni.Use a delegate to set options values. L'app di esempio usa la 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;
}

Nel codice seguente viene aggiunto un secondo servizio IConfigureOptions<TOptions> al contenitore di servizi.In the following code, a second IConfigureOptions<TOptions> service is added to the service container. Viene usato un delegato per configurare l'associazione a 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}";

È possibile aggiungere più provider di configurazione.You can add multiple configuration providers. I provider di configurazione sono disponibili dai pacchetti NuGet e vengono applicati nell'ordine in cui sono registrati.Configuration providers are available from NuGet packages and are applied in the order that they're registered. Per ulteriori informazioni, vedere Configurazione in ASP.NET Core.For more information, see Configurazione in ASP.NET Core.

Ogni chiamata a Configure aggiunge un servizio IConfigureOptions<TOptions> al contenitore di servizi.Each call to Configure adds an IConfigureOptions<TOptions> service to the service container. Nell'esempio precedente i valori di Option1 e Option2 sono entrambi specificati in appsettings.json, mentre i valori di Option1 e Option2 sono sottoposti a override dal delegato configurato.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 sono abilitati più servizi di configurazione, l'origine di configurazione più recente specificata ha priorità e imposta il valore di configurazione.When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value. Quando viene eseguita l'app, il metodo OnGet del modello di pagina restituisce una stringa che mostra i valori delle classi delle opzioni: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

Configurazione delle opzioni secondarieSuboptions configuration

La configurazione delle opzioni secondarie è illustrata nell'Esempio #3 nell'app di esempio.Suboptions configuration is demonstrated as Example #3 in the sample app.

Le app devono creare classi di opzioni che riguardano gruppi di scenari (classi) specifici nell'app.Apps should create options classes that pertain to specific scenario groups (classes) in the app. Le parti dell'app che richiedono valori di configurazione devono avere accesso solo ai valori di configurazione necessari.Parts of the app that require configuration values should only have access to the configuration values that they use.

Durante l'associazione delle opzioni alla configurazione, ogni proprietà del tipo di opzioni viene associata a una chiave di configurazione con 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:]. Ad esempio, la proprietà MyOptions.Option1 viene associata alla chiave Option1, che viene letta dalla proprietà option1 in appsettings.json.For example, the MyOptions.Option1 property is bound to the key Option1, which is read from the option1 property in appsettings.json.

Nel codice seguente viene aggiunto un terzo servizio IConfigureOptions<TOptions> al contenitore di servizi.In the following code, a third IConfigureOptions<TOptions> service is added to the service container. MySubOptions viene associato alla sezione subsection del file 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"));

Il metodo di estensione GetSection richiede il pacchetto NuGet Microsoft.Extensions.Options.ConfigurationExtensions.The GetSection extension method requires the Microsoft.Extensions.Options.ConfigurationExtensions NuGet package. Se l'app usa il metapacchetto Microsoft.AspNetCore.App (ASP.NET Core 2.1 o versioni successive), il pacchetto è incluso automaticamente.If the app uses the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later), the package is automatically included.

Il file appsettings.json dell'esempio definisce un membro subsection con chiavi per 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": "*"
}

La classe MySubOptions definisce le proprietà SubOption1 e SubOption2 per contenere i valori delle opzioni (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; }
}

Il metodo OnGet del modello di pagina restituisce una stringa con i valori delle opzioni (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 viene eseguita l'app, il metodo OnGet restituisce una stringa che mostra i valori delle classi delle opzioni secondarie:When the app is run, the OnGet method returns a string showing the suboption class values:

subOption1 = subvalue1_from_json, subOption2 = 200

Opzioni fornite da un modello di visualizzazione o con l'inserimento diretto della visualizzazioneOptions provided by a view model or with direct view injection

Le opzioni fornite da un modello di visualizzazione o con l'inserimento diretto della visualizzazione sono illustrate nell'Esempio #4 nell'app di esempio.Options provided by a view model or with direct view injection is demonstrated as Example #4 in the sample app.

Le opzioni possono essere rese disponibili in un modello di visualizzazione oppure inserendo IOptionsMonitor<TOptions> direttamente in una visualizzazione (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;

L'app di esempio mostra come inserire IOptionsMonitor<MyOptions> con una direttiva @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 l'app viene eseguita, i valori delle opzioni sono visibili nella pagina di cui è stato eseguito il rendering:When the app is run, the options values are shown in the rendered page:

I valori delle opzioni Option1: value1_from_json e Option2: -1 vengono caricati dal modello e tramite inserimento nella visualizzazione.

Ricaricare i dati di configurazione con IOptionsSnapshotReload configuration data with IOptionsSnapshot

Il ricaricamento dei dati di configurazione con IOptionsSnapshot<TOptions> è illustrato nell'Esempio #5 nell'app di esempio.Reloading configuration data with IOptionsSnapshot<TOptions> is demonstrated in Example #5 in the sample app.

IOptionsSnapshot<TOptions> supporta il ricaricamento delle opzioni con un overhead di elaborazione minimo.IOptionsSnapshot<TOptions> supports reloading options with minimal processing overhead.

Le opzioni vengono calcolate una volta per richiesta quando viene eseguito l'accesso e la memorizzazione nella cache per la durata della richiesta.Options are computed once per request when accessed and cached for the lifetime of the request.

L'esempio seguente illustra la creazione di un nuovo IOptionsSnapshot<TOptions> dopo le modifiche ad 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). Più richieste al server restituiscono valori costanti forniti dal file appsettings.json fino a quando il file non viene modificato e la configurazione non viene ricaricata.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}";

L'immagine seguente illustra i valori iniziali option1 e option2 caricati dal file 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

Modificare i valori nel file appsettings.json in value1_from_json UPDATED e 200.Change the values in the appsettings.json file to value1_from_json UPDATED and 200. Salvare il file appsettings.json.Save the appsettings.json file. Aggiornare il browser per visualizzare i valori delle opzioni aggiornati:Refresh the browser to see that the options values are updated:

snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200

Supporto delle opzioni denominate con IConfigureNamedOptionsNamed options support with IConfigureNamedOptions

Il supporto delle opzioni denominate con IConfigureNamedOptions<TOptions> è illustrato nell'Esempio #6 nell'app di esempio.Named options support with IConfigureNamedOptions<TOptions> is demonstrated as Example #6 in the sample app.

Il supporto delle opzioni denominate consente all'app di distinguere le configurazioni delle opzioni denominate.Named options support allows the app to distinguish between named options configurations. Nell'app di esempio le opzioni denominate vengono dichiarate con OptionsServiceCollectionExtensions.Configure, che chiama il metodo di estensione 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";
});

L'app di esempio accede alle opzioni denominate con 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}";

Eseguendo l'app di esempio, vengono restituite le opzioni denominate: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

I valori named_options_1 vengono specificati dalla configurazione, caricata dal file appsettings.json.named_options_1 values are provided from configuration, which are loaded from the appsettings.json file. I valori named_options_2 sono specificati da:named_options_2 values are provided by:

  • Delegato named_options_2 in ConfigureServices per Option1.The named_options_2 delegate in ConfigureServices for Option1.
  • Valore predefinito per Option2 specificato dalla classe MyOptions.The default value for Option2 provided by the MyOptions class.

Configurare tutte le opzioni con il metodo ConfigureAllConfigure all options with the ConfigureAll method

Configurare tutte le istanze delle opzioni con il metodo ConfigureAll.Configure all options instances with the ConfigureAll method. Il codice seguente configura Option1 per tutte le istanze di configurazione con un valore comune.The following code configures Option1 for all configuration instances with a common value. Aggiungere manualmente il codice seguente al metodo Startup.ConfigureServices:Add the following code manually to the Startup.ConfigureServices method:

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

L'esecuzione dell'app di esempio dopo l'aggiunta del codice produce il risultato seguente: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

Nota

Tutte le opzioni sono istanze denominate.All options are named instances. Le istanze di IConfigureOptions<TOptions> esistenti sono trattate come se fossero indirizzate all'istanza di Options.DefaultName, ovvero string.Empty.Existing IConfigureOptions<TOptions> instances are treated as targeting the Options.DefaultName instance, which is string.Empty. IConfigureNamedOptions<TOptions> implementa anche IConfigureOptions<TOptions>.IConfigureNamedOptions<TOptions> also implements IConfigureOptions<TOptions>. L'implementazione predefinita di IOptionsFactory<TOptions> include la logica per usarle in modo appropriato.The default implementation of the IOptionsFactory<TOptions> has logic to use each appropriately. L'opzione denominata null viene usata per avere come destinazione tutte le istanze denominate anziché un'istanza specifica denominata (questa convenzione è usata da ConfigureAll e PostConfigureAll).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> viene usata per configurare le istanze di TOptions.OptionsBuilder<TOptions> is used to configure TOptions instances. OptionsBuilder semplifica la creazione di opzioni denominate perché è costituita da un singolo parametro nella chiamata iniziale ad AddOptions<TOptions>(string optionsName) invece di essere visualizzata in tutte le chiamate successive.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. La convalida delle opzioni e gli overload ConfigureOptions che accettano le dipendenze dei servizi sono disponibili solo tramite 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");

Usare i servizi di inserimento delle dipendenze per configurare le opzioniUse DI services to configure options

È possibile accedere ad altri servizi dall'inserimento delle dipendenze durante la configurazione delle opzioni in due modi:You can access other services from dependency injection while configuring options in two ways:

È consigliabile passare un delegato di configurazione a Configure perché la creazione di un servizio è più complessa.We recommend passing a configuration delegate to Configure, since creating a service is more complex. La creazione di un tipo personalizzato equivale alle operazioni che il framework esegue automaticamente quando si usa Configure.Creating your own type is equivalent to what the framework does for you when you use Configure. La chiamata a Configure registra un'interfaccia IConfigureNamedOptions<TOptions> generica temporanea, che ha un costruttore che accetta i tipi di servizi generici specificati.Calling Configure registers a transient generic IConfigureNamedOptions<TOptions>, which has a constructor that accepts the generic service types specified.

Convalida delle opzioniOptions validation

La convalida le opzioni consente di convalidare le opzioni quando vengono configurate.Options validation allows you to validate options when options are configured. Chiamare Validate con un metodo di convalida che restituisce true se le opzioni sono valide e false se non sono valide: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"
}

L'esempio precedente imposta l'istanza di opzioni denominata su optionalOptionsName.The preceding example sets the named options instance to optionalOptionsName. L'istanza di opzioni predefinita è Options.DefaultName.The default options instance is Options.DefaultName.

La convalida viene eseguita quando viene creata l'istanza di opzioni.Validation runs when the options instance is created. L'istanza di opzioni supera sicuramente la convalida al primo accesso.Your options instance is guaranteed to pass validation the first time it's accessed.

Importante

La convalida delle opzioni non protegge da eventuali modifiche dopo la configurazione e la convalida iniziali delle opzioni.Options validation doesn't guard against options modifications after the options are initially configured and validated.

Il metodo Validate accetta Func<TOptions, bool>.The Validate method accepts a Func<TOptions, bool>. Per personalizzare completamente la convalida, implementare IValidateOptions<TOptions>, che consente:To fully customize validation, implement IValidateOptions<TOptions>, which allows:

  • La convalida di più tipi di opzioni: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>Validation of multiple options types: class ValidateTwo : IValidateOptions<Option1>, IValidationOptions<Option2>
  • La convalida che dipende da un altro tipo di opzione: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)Validation that depends on another option type: public DependsOnAnotherOptionValidator(IOptionsMonitor<AnotherOption> options)

IValidateOptions convalida:IValidateOptions validates:

  • Un'istanza di opzioni denominata specifica.A specific named options instance.
  • Tutte le opzioni quando name è null.All options when name is null.

Restituire ValidateOptionsResult dall'implementazione dell'interfaccia:Return a ValidateOptionsResult from your implementation of the interface:

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

La convalida basata sull'annotazione dei dati è disponibile dal pacchetto Microsoft.Extensions.Options.DataAnnotations chiamando il metodo ValidateDataAnnotations su OptionsBuilder<TOptions>.Data Annotation-based validation is available from the Microsoft.Extensions.Options.DataAnnotations package by calling the ValidateDataAnnotations method on OptionsBuilder<TOptions>. Microsoft.Extensions.Options.DataAnnotations è incluso nel metapacchetto Microsoft. AspNetCore. app.Microsoft.Extensions.Options.DataAnnotations is included in the Microsoft.AspNetCore.App metapackage.

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>>().CurrentValue);
    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.'.");
}

La convalida eager (fallimento e risposta immediata agli errori all'avvio) è pianificata per una versione futura.Eager validation (fail fast at startup) is under consideration for a future release.

Post-configurazione delle opzioniOptions post-configuration

Impostare la post-configurazione con IPostConfigureOptions<TOptions>.Set post-configuration with IPostConfigureOptions<TOptions>. La post-configurazione viene eseguita dopo il completamento della configurazione di tutte le IConfigureOptions<TOptions>:Post-configuration runs after all IConfigureOptions<TOptions> configuration occurs:

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

PostConfigure è disponibile per la post-configurazione delle opzioni denominate:PostConfigure is available to post-configure named options:

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

Usare PostConfigureAll per la post-configurazione di tutte le istanze di configurazione:Use PostConfigureAll to post-configure all configuration instances:

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

Accesso alle opzioni durante l'avvioAccessing options during startup

IOptions<TOptions> e IOptionsMonitor<TOptions> possono essere usate in Startup.Configure, perché i servizi vengono compilati prima dell'esecuzione del metodo 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;
}

Non usare IOptions<TOptions> oppure IOptionsMonitor<TOptions> in Startup.ConfigureServices.Don't use IOptions<TOptions> or IOptionsMonitor<TOptions> in Startup.ConfigureServices. Le opzioni potrebbero avere uno stato incoerente a causa dell'ordinamento delle registrazioni dei servizi.An inconsistent options state may exist due to the ordering of service registrations.

Il modello di opzioni usa le classi per rappresentare i gruppi di impostazioni correlate.The options pattern uses classes to represent groups of related settings. Quando le impostazioni di configurazione vengono isolate in base allo scenario in classi separate, l'app aderisce a due importanti principi di progettazione del software:When configuration settings are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

Le opzioni offrono anche un meccanismo per convalidare i dati di configurazione.Options also provide a mechanism to validate configuration data. Per altre informazioni, vedere la sezione Opzioni di convalida.For more information, see the Options validation section.

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

PrerequisitesPrerequisites

Fare riferimento al metapacchetto Microsoft.AspNetCore.App oppure aggiungere un riferimento al pacchetto Microsoft.Extensions.Options.ConfigurationExtensions.Reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Options.ConfigurationExtensions package.

Interfacce per le opzioniOptions interfaces

IOptionsMonitor<TOptions> consente di recuperare le opzioni e gestire le notifiche di opzioni per le istanze TOptions.IOptionsMonitor<TOptions> is used to retrieve options and manage options notifications for TOptions instances. IOptionsMonitor<TOptions> supporta gli scenari seguenti:IOptionsMonitor<TOptions> supports the following scenarios:

Gli scenari di post-configurazione consentono di impostare o modificare le opzioni dopo la configurazione di tutte le IConfigureOptions<TOptions>.Post-configuration scenarios allow you to set or change options after all IConfigureOptions<TOptions> configuration occurs.

IOptionsFactory<TOptions> è responsabile della creazione di nuove istanze di opzioni.IOptionsFactory<TOptions> is responsible for creating new options instances. Include un singolo metodo Create.It has a single Create method. L'implementazione predefinita accetta tutte le interfacce IConfigureOptions<TOptions> e IPostConfigureOptions<TOptions> registrate ed esegue tutte le configurazioni, seguite dalla post-configurazione.The default implementation takes all registered IConfigureOptions<TOptions> and IPostConfigureOptions<TOptions> and runs all the configurations first, followed by the post-configuration. Fa distinzione tra IConfigureNamedOptions<TOptions> e IConfigureOptions<TOptions> e chiama solo l'interfaccia appropriata.It distinguishes between IConfigureNamedOptions<TOptions> and IConfigureOptions<TOptions> and only calls the appropriate interface.

IOptionsMonitorCache<TOptions> viene usata da IOptionsMonitor<TOptions> per memorizzare nella cache le istanze di TOptions.IOptionsMonitorCache<TOptions> is used by IOptionsMonitor<TOptions> to cache TOptions instances. IOptionsMonitorCache<TOptions> invalida le istanze delle opzioni nel monitoraggio in modo che il valore venga ricalcolato (TryRemove).The IOptionsMonitorCache<TOptions> invalidates options instances in the monitor so that the value is recomputed (TryRemove). I valori possono essere introdotti manualmente con TryAdd.Values can be manually introduced with TryAdd. Il metodo Clear viene usato quando tutte le istanze denominate devono essere ricreate su richiesta.The Clear method is used when all named instances should be recreated on demand.

IOptionsSnapshot<TOptions> è utile negli scenari in cui le opzioni devono essere ricalcolate a ogni richiesta.IOptionsSnapshot<TOptions> is useful in scenarios where options should be recomputed on every request. Per altre informazioni, vedere la sezione Ricaricare i dati di configurazione con IOptionsSnapshot.For more information, see the Reload configuration data with IOptionsSnapshot section.

IOptions<TOptions> può essere usata a supporto delle opzioni.IOptions<TOptions> can be used to support options. Tuttavia IOptions<TOptions> non supporta gli scenari precedenti di IOptionsMonitor<TOptions>.However, IOptions<TOptions> doesn't support the preceding scenarios of IOptionsMonitor<TOptions>. È possibile continuare a usare IOptions<TOptions> in framework e librerie esistenti che già usano l'interfaccia IOptions<TOptions> e non richiedono gli scenari forniti da 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>.

Configurazione delle opzioni generaliGeneral options configuration

La configurazione delle opzioni generali è illustrata nell'Esempio #1 nell'app di esempio.General options configuration is demonstrated as Example #1 in the sample app.

Una classe di opzioni deve essere non astratta con un costruttore pubblico senza parametri.An options class must be non-abstract with a public parameterless constructor. La classe seguente, MyOptions, ha due proprietà, Option1 e Option2.The following class, MyOptions, has two properties, Option1 and Option2. Sebbene l'impostazione dei valori predefiniti sia facoltativa, il costruttore della classe nell'esempio seguente imposta il valore predefinito di Option1.Setting default values is optional, but the class constructor in the following example sets the default value of Option1. Option2 ha un valore impostato tramite l'inizializzazione diretta della proprietà (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;
}

La classe MyOptions viene aggiunta al contenitore di servizi con Configure e associata alla configurazione: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);

Il modello di pagina seguente usa l'inserimento delle dipendenze del costruttore con IOptionsMonitor<TOptions> per accedere alle impostazioni (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}";

Il file appsettings.json dell'esempio specifica i valori di 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 viene eseguita l'app, il metodo OnGet del modello di pagina restituisce una stringa che mostra i valori delle classi delle opzioni: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

Nota

Se si usa un ConfigurationBuilder personalizzato per caricare la configurazione delle opzioni da un file di impostazioni, verificare che il percorso base sia impostato correttamente: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);

L'impostazione esplicita del percorso base non è necessaria se si carica la configurazione delle opzioni dal file di impostazioni tramite CreateDefaultBuilder.Explicitly setting the base path isn't required when loading options configuration from the settings file via CreateDefaultBuilder.

Configurare opzioni semplici con un delegatoConfigure simple options with a delegate

La configurazione di opzioni semplici con un delegato è illustrata nell'Esempio #2 nell'app di esempio.Configuring simple options with a delegate is demonstrated as Example #2 in the sample app.

Usare un delegato per impostare i valori delle opzioni.Use a delegate to set options values. L'app di esempio usa la 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;
}

Nel codice seguente viene aggiunto un secondo servizio IConfigureOptions<TOptions> al contenitore di servizi.In the following code, a second IConfigureOptions<TOptions> service is added to the service container. Viene usato un delegato per configurare l'associazione a 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}";

È possibile aggiungere più provider di configurazione.You can add multiple configuration providers. I provider di configurazione sono disponibili dai pacchetti NuGet e vengono applicati nell'ordine in cui sono registrati.Configuration providers are available from NuGet packages and are applied in the order that they're registered. Per ulteriori informazioni, vedere Configurazione in ASP.NET Core.For more information, see Configurazione in ASP.NET Core.

Ogni chiamata a Configure aggiunge un servizio IConfigureOptions<TOptions> al contenitore di servizi.Each call to Configure adds an IConfigureOptions<TOptions> service to the service container. Nell'esempio precedente i valori di Option1 e Option2 sono entrambi specificati in appsettings.json, mentre i valori di Option1 e Option2 sono sottoposti a override dal delegato configurato.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 sono abilitati più servizi di configurazione, l'origine di configurazione più recente specificata ha priorità e imposta il valore di configurazione.When more than one configuration service is enabled, the last configuration source specified wins and sets the configuration value. Quando viene eseguita l'app, il metodo OnGet del modello di pagina restituisce una stringa che mostra i valori delle classi delle opzioni: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

Configurazione delle opzioni secondarieSuboptions configuration

La configurazione delle opzioni secondarie è illustrata nell'Esempio #3 nell'app di esempio.Suboptions configuration is demonstrated as Example #3 in the sample app.

Le app devono creare classi di opzioni che riguardano gruppi di scenari (classi) specifici nell'app.Apps should create options classes that pertain to specific scenario groups (classes) in the app. Le parti dell'app che richiedono valori di configurazione devono avere accesso solo ai valori di configurazione necessari.Parts of the app that require configuration values should only have access to the configuration values that they use.

Durante l'associazione delle opzioni alla configurazione, ogni proprietà del tipo di opzioni viene associata a una chiave di configurazione con 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:]. Ad esempio, la proprietà MyOptions.Option1 viene associata alla chiave Option1, che viene letta dalla proprietà option1 in appsettings.json.For example, the MyOptions.Option1 property is bound to the key Option1, which is read from the option1 property in appsettings.json.

Nel codice seguente viene aggiunto un terzo servizio IConfigureOptions<TOptions> al contenitore di servizi.In the following code, a third IConfigureOptions<TOptions> service is added to the service container. MySubOptions viene associato alla sezione subsection del file 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"));

Il metodo di estensione GetSection richiede il pacchetto NuGet Microsoft.Extensions.Options.ConfigurationExtensions.The GetSection extension method requires the Microsoft.Extensions.Options.ConfigurationExtensions NuGet package. Se l'app usa il metapacchetto Microsoft.AspNetCore.App (ASP.NET Core 2.1 o versioni successive), il pacchetto è incluso automaticamente.If the app uses the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later), the package is automatically included.

Il file appsettings.json dell'esempio definisce un membro subsection con chiavi per 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": "*"
}

La classe MySubOptions definisce le proprietà SubOption1 e SubOption2 per contenere i valori delle opzioni (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; }
}

Il metodo OnGet del modello di pagina restituisce una stringa con i valori delle opzioni (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 viene eseguita l'app, il metodo OnGet restituisce una stringa che mostra i valori delle classi delle opzioni secondarie:When the app is run, the OnGet method returns a string showing the suboption class values:

subOption1 = subvalue1_from_json, subOption2 = 200

Opzioni fornite da un modello di visualizzazione o con l'inserimento diretto della visualizzazioneOptions provided by a view model or with direct view injection

Le opzioni fornite da un modello di visualizzazione o con l'inserimento diretto della visualizzazione sono illustrate nell'Esempio #4 nell'app di esempio.Options provided by a view model or with direct view injection is demonstrated as Example #4 in the sample app.

Le opzioni possono essere rese disponibili in un modello di visualizzazione oppure inserendo IOptionsMonitor<TOptions> direttamente in una visualizzazione (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;

L'app di esempio mostra come inserire IOptionsMonitor<MyOptions> con una direttiva @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 l'app viene eseguita, i valori delle opzioni sono visibili nella pagina di cui è stato eseguito il rendering:When the app is run, the options values are shown in the rendered page:

I valori delle opzioni Option1: value1_from_json e Option2: -1 vengono caricati dal modello e tramite inserimento nella visualizzazione.

Ricaricare i dati di configurazione con IOptionsSnapshotReload configuration data with IOptionsSnapshot

Il ricaricamento dei dati di configurazione con IOptionsSnapshot<TOptions> è illustrato nell'Esempio #5 nell'app di esempio.Reloading configuration data with IOptionsSnapshot<TOptions> is demonstrated in Example #5 in the sample app.

IOptionsSnapshot<TOptions> supporta il ricaricamento delle opzioni con un overhead di elaborazione minimo.IOptionsSnapshot<TOptions> supports reloading options with minimal processing overhead.

Le opzioni vengono calcolate una volta per richiesta quando viene eseguito l'accesso e la memorizzazione nella cache per la durata della richiesta.Options are computed once per request when accessed and cached for the lifetime of the request.

L'esempio seguente illustra la creazione di un nuovo IOptionsSnapshot<TOptions> dopo le modifiche ad 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). Più richieste al server restituiscono valori costanti forniti dal file appsettings.json fino a quando il file non viene modificato e la configurazione non viene ricaricata.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}";

L'immagine seguente illustra i valori iniziali option1 e option2 caricati dal file 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

Modificare i valori nel file appsettings.json in value1_from_json UPDATED e 200.Change the values in the appsettings.json file to value1_from_json UPDATED and 200. Salvare il file appsettings.json.Save the appsettings.json file. Aggiornare il browser per visualizzare i valori delle opzioni aggiornati:Refresh the browser to see that the options values are updated:

snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200

Supporto delle opzioni denominate con IConfigureNamedOptionsNamed options support with IConfigureNamedOptions

Il supporto delle opzioni denominate con IConfigureNamedOptions<TOptions> è illustrato nell'Esempio #6 nell'app di esempio.Named options support with IConfigureNamedOptions<TOptions> is demonstrated as Example #6 in the sample app.

Il supporto delle opzioni denominate consente all'app di distinguere le configurazioni delle opzioni denominate.Named options support allows the app to distinguish between named options configurations. Nell'app di esempio le opzioni denominate vengono dichiarate con OptionsServiceCollectionExtensions.Configure, che chiama il metodo di estensione 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";
});

L'app di esempio accede alle opzioni denominate con 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}";

Eseguendo l'app di esempio, vengono restituite le opzioni denominate: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

I valori named_options_1 vengono specificati dalla configurazione, caricata dal file appsettings.json.named_options_1 values are provided from configuration, which are loaded from the appsettings.json file. I valori named_options_2 sono specificati da:named_options_2 values are provided by:

  • Delegato named_options_2 in ConfigureServices per Option1.The named_options_2 delegate in ConfigureServices for Option1.
  • Valore predefinito per Option2 specificato dalla classe MyOptions.The default value for Option2 provided by the MyOptions class.

Configurare tutte le opzioni con il metodo ConfigureAllConfigure all options with the ConfigureAll method

Configurare tutte le istanze delle opzioni con il metodo ConfigureAll.Configure all options instances with the ConfigureAll method. Il codice seguente configura Option1 per tutte le istanze di configurazione con un valore comune.The following code configures Option1 for all configuration instances with a common value. Aggiungere manualmente il codice seguente al metodo Startup.ConfigureServices:Add the following code manually to the Startup.ConfigureServices method:

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

L'esecuzione dell'app di esempio dopo l'aggiunta del codice produce il risultato seguente: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

Nota

Tutte le opzioni sono istanze denominate.All options are named instances. Le istanze di IConfigureOptions<TOptions> esistenti sono trattate come se fossero indirizzate all'istanza di Options.DefaultName, ovvero string.Empty.Existing IConfigureOptions<TOptions> instances are treated as targeting the Options.DefaultName instance, which is string.Empty. IConfigureNamedOptions<TOptions> implementa anche IConfigureOptions<TOptions>.IConfigureNamedOptions<TOptions> also implements IConfigureOptions<TOptions>. L'implementazione predefinita di IOptionsFactory<TOptions> include la logica per usarle in modo appropriato.The default implementation of the IOptionsFactory<TOptions> has logic to use each appropriately. L'opzione denominata null viene usata per avere come destinazione tutte le istanze denominate anziché un'istanza specifica denominata (questa convenzione è usata da ConfigureAll e PostConfigureAll).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> viene usata per configurare le istanze di TOptions.OptionsBuilder<TOptions> is used to configure TOptions instances. OptionsBuilder semplifica la creazione di opzioni denominate perché è costituita da un singolo parametro nella chiamata iniziale ad AddOptions<TOptions>(string optionsName) invece di essere visualizzata in tutte le chiamate successive.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. La convalida delle opzioni e gli overload ConfigureOptions che accettano le dipendenze dei servizi sono disponibili solo tramite 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");

Usare i servizi di inserimento delle dipendenze per configurare le opzioniUse DI services to configure options

È possibile accedere ad altri servizi dall'inserimento delle dipendenze durante la configurazione delle opzioni in due modi:You can access other services from dependency injection while configuring options in two ways:

È consigliabile passare un delegato di configurazione a Configure perché la creazione di un servizio è più complessa.We recommend passing a configuration delegate to Configure, since creating a service is more complex. La creazione di un tipo personalizzato equivale alle operazioni che il framework esegue automaticamente quando si usa Configure.Creating your own type is equivalent to what the framework does for you when you use Configure. La chiamata a Configure registra un'interfaccia IConfigureNamedOptions<TOptions> generica temporanea, che ha un costruttore che accetta i tipi di servizi generici specificati.Calling Configure registers a transient generic IConfigureNamedOptions<TOptions>, which has a constructor that accepts the generic service types specified.

Post-configurazione delle opzioniOptions post-configuration

Impostare la post-configurazione con IPostConfigureOptions<TOptions>.Set post-configuration with IPostConfigureOptions<TOptions>. La post-configurazione viene eseguita dopo il completamento della configurazione di tutte le IConfigureOptions<TOptions>:Post-configuration runs after all IConfigureOptions<TOptions> configuration occurs:

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

PostConfigure è disponibile per la post-configurazione delle opzioni denominate:PostConfigure is available to post-configure named options:

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

Usare PostConfigureAll per la post-configurazione di tutte le istanze di configurazione:Use PostConfigureAll to post-configure all configuration instances:

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

Accesso alle opzioni durante l'avvioAccessing options during startup

IOptions<TOptions> e IOptionsMonitor<TOptions> possono essere usate in Startup.Configure, perché i servizi vengono compilati prima dell'esecuzione del metodo 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;
}

Non usare IOptions<TOptions> oppure IOptionsMonitor<TOptions> in Startup.ConfigureServices.Don't use IOptions<TOptions> or IOptionsMonitor<TOptions> in Startup.ConfigureServices. Le opzioni potrebbero avere uno stato incoerente a causa dell'ordinamento delle registrazioni dei servizi.An inconsistent options state may exist due to the ordering of service registrations.

Risorse aggiuntiveAdditional resources