--- title: Options pattern in ASP.NET Core author: guardrex description: Discover how to use the options pattern to represent groups of related settings in ASP.NET Core apps. manager: wpickett ms.author: riande ms.custom: mvc ms.date: 11/28/2017 ms.prod: asp.net-core ms.technology: aspnet ms.topic: article uid: fundamentals/configuration/options --- # Options pattern in ASP.NET Core By [Luke Latham](https://github.com/guardrex) The options pattern uses classes to represent groups of related settings. When configuration settings are isolated by feature into separate classes, the app adheres to two important software engineering principles: * The [Interface Segregation Principle (ISP)](http://deviq.com/interface-segregation-principle/): Features (classes) that depend on configuration settings depend only on the configuration settings that they use. * [Separation of Concerns](http://deviq.com/separation-of-concerns/): Settings for different parts of the app aren't dependent or coupled to one another. [View or download sample code](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/options/sample) ([how to download](xref:tutorials/index#how-to-download-a-sample)) This article is easier to follow with the sample app. ## Basic options configuration Basic options configuration is demonstrated as Example #1 in the [sample app](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/options/sample). An options class must be non-abstract with a public parameterless constructor. The following class, `MyOptions`, has two properties, `Option1` and `Option2`. Setting default values is optional, but the class constructor in the following example sets the default value of `Option1`. `Option2` has a default value set by initializing the property directly (*Models/MyOptions.cs*): [!code-csharp[](options/sample/Models/MyOptions.cs?name=snippet1)] The `MyOptions` class is added to the service container with [IConfigureOptions<TOptions>](/dotnet/api/microsoft.extensions.options.iconfigureoptions-1) and bound to configuration: [!code-csharp[](options/sample/Startup.cs?name=snippet_Example1)] The following page model uses [constructor dependency injection](xref:fundamentals/dependency-injection#what-is-dependency-injection) with [IOptions<TOptions>](/dotnet/api/Microsoft.Extensions.Options.IOptions-1) to access the settings (*Pages/Index.cshtml.cs*): [!code-csharp[](options/sample/Pages/Index.cshtml.cs?range=9)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet2&highlight=2,8)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet_Example1)] The sample's *appsettings.json* file specifies values for `option1` and `option2`: [!code-json[](options/sample/appsettings.json)] When the app is run, the page model's `OnGet` method returns a string showing the option class values: ```html option1 = value1_from_json, option2 = -1 ``` ## Configure simple options with a delegate Configuring simple options with a delegate is demonstrated as Example #2 in the [sample app](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/options/sample). Use a delegate to set options values. The sample app uses the `MyOptionsWithDelegateConfig` class (*Models/MyOptionsWithDelegateConfig.cs*): [!code-csharp[](options/sample/Models/MyOptionsWithDelegateConfig.cs?name=snippet1)] In the following code, a second `IConfigureOptions` service is added to the service container. It uses a delegate to configure the binding with `MyOptionsWithDelegateConfig`: [!code-csharp[](options/sample/Startup.cs?name=snippet_Example2)] *Index.cshtml.cs*: [!code-csharp[](options/sample/Pages/Index.cshtml.cs?range=10)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet2&highlight=3,9)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet_Example2)] You can add multiple configuration providers. Configuration providers are available in NuGet packages. They're applied in order that they're registered. Each call to [Configure<TOptions>](/dotnet/api/microsoft.extensions.options.iconfigureoptions-1.configure) adds an `IConfigureOptions` service to the service container. 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. When more than one configuration service is enabled, the last configuration source specified *wins* and sets the configuration value. When the app is run, the page model's `OnGet` method returns a string showing the option class values: ```html delegate_option1 = value1_configured_by_delgate, delegate_option2 = 500 ``` ## Suboptions configuration Suboptions configuration is demonstrated as Example #3 in the [sample app](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/options/sample). Apps should create options classes that pertain to specific feature groups (classes) in the app. Parts of the app that require configuration values should only have access to the configuration values that they use. When binding options to configuration, each property in the options type is bound to a configuration key of the form `property[:sub-property:]`. For example, the `MyOptions.Option1` property is bound to the key `Option1`, which is read from the `option1` property in *appsettings.json*. In the following code, a third `IConfigureOptions` service is added to the service container. It binds `MySubOptions` to the section `subsection` of the *appsettings.json* file: [!code-csharp[](options/sample/Startup.cs?name=snippet_Example3)] The `GetSection` extension method requires the [Microsoft.Extensions.Options.ConfigurationExtensions](https://www.nuget.org/packages/Microsoft.Extensions.Options.ConfigurationExtensions/) NuGet package. If the app uses the [Microsoft.AspNetCore.All](https://www.nuget.org/packages/Microsoft.AspNetCore.All/) metapackage, the package is automatically included. The sample's *appsettings.json* file defines a `subsection` member with keys for `suboption1` and `suboption2`: [!code-json[](options/sample/appsettings.json?highlight=4-7)] The `MySubOptions` class defines properties, `SubOption1` and `SubOption2`, to hold the sub-option values (*Models/MySubOptions.cs*): [!code-csharp[](options/sample/Models/MySubOptions.cs?name=snippet1)] The page model's `OnGet` method returns a string with the sub-option values (*Pages/Index.cshtml.cs*): [!code-csharp[](options/sample/Pages/Index.cshtml.cs?range=11)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet2&highlight=4,10)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet_Example3)] When the app is run, the `OnGet` method returns a string showing the sub-option class values: ```html subOption1 = subvalue1_from_json, subOption2 = 200 ``` ## Options provided by a view model or with direct view injection Options provided by a view model or with direct view injection is demonstrated as Example #4 in the [sample app](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/options/sample). Options can be supplied in a view model or by injecting `IOptions` directly into a view (*Pages/Index.cshtml.cs*): [!code-csharp[](options/sample/Pages/Index.cshtml.cs?range=9)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet2&highlight=2,8)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet_Example4)] For direct injection, inject `IOptions` with an `@inject` directive: [!code-cshtml[](options/sample/Pages/Index.cshtml?range=1-10&highlight=5)] When the app is run, the option values are shown in the rendered page: ![Options values Option1: value1_from_json and Option2: -1 are loaded from the model and by injection into the view.](options/_static/view.png) ## Reload configuration data with IOptionsSnapshot Reloading configuration data with `IOptionsSnapshot` is demonstrated in Example #5 in the [sample app](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/options/sample). *Requires ASP.NET Core 1.1 or later.* [IOptionsSnapshot](/dotnet/api/microsoft.extensions.options.ioptionssnapshot-1) supports reloading options with minimal processing overhead. In ASP.NET Core 1.1, `IOptionsSnapshot` is a snapshot of [IOptionsMonitor<TOptions>](/dotnet/api/microsoft.extensions.options.ioptionsmonitor-1) and updates automatically whenever the monitor triggers changes based on the data source changing. In ASP.NET Core 2.0 and later, options are computed once per request when accessed and cached for the lifetime of the request. The following example demonstrates how a new `IOptionsSnapshot` is created after *appsettings.json* changes (*Pages/Index.cshtml.cs*). Multiple requests to the server return constant values provided by the *appsettings.json* file until the file is changed and configuration reloads. [!code-csharp[](options/sample/Pages/Index.cshtml.cs?range=12)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet2&highlight=5,11)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet_Example5)] The following image shows the initial `option1` and `option2` values loaded from the *appsettings.json* file: ```html snapshot option1 = value1_from_json, snapshot option2 = -1 ``` Change the values in the *appsettings.json* file to `value1_from_json UPDATED` and `200`. Save the *appsettings.json* file. Refresh the browser to see that the options values are updated: ```html snapshot option1 = value1_from_json UPDATED, snapshot option2 = 200 ``` ## Named options support with IConfigureNamedOptions Named options support with [IConfigureNamedOptions](/dotnet/api/microsoft.extensions.options.iconfigurenamedoptions-1) is demonstrated as Example #6 in the [sample app](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/options/sample). *Requires ASP.NET Core 2.0 or later.* *Named options* support allows the app to distinguish between named options configurations. In the sample app, named options are declared with the [ConfigureNamedOptions<TOptions>.Configure](/dotnet/api/microsoft.extensions.options.configurenamedoptions-1.configure) method: [!code-csharp[](options/sample/Startup.cs?name=snippet_Example6)] The sample app accesses the named options with [IOptionsSnapshot<TOptions>.Get](/dotnet/api/microsoft.extensions.options.ioptionssnapshot-1.get) (*Pages/Index.cshtml.cs*): [!code-csharp[](options/sample/Pages/Index.cshtml.cs?range=13-14)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet2&highlight=6,12-13)] [!code-csharp[](options/sample/Pages/Index.cshtml.cs?name=snippet_Example6)] Running the sample app, the named options are returned: ```html named_options_1: option1 = value1_from_json, option2 = -1 named_options_2: option1 = named_options_2_value1_from_action, option2 = 5 ``` `named_options_1` values are provided from configuration, which are loaded from the *appsettings.json* file. `named_options_2` values are provided by: * The `named_options_2` delegate in `ConfigureServices` for `Option1`. * The default value for `Option2` provided by the `MyOptions` class. Configure all named options instances with the [OptionsServiceCollectionExtensions.ConfigureAll](/dotnet/api/microsoft.extensions.dependencyinjection.optionsservicecollectionextensions.configureall) method. The following code configures `Option1` for all named configuration instances with a common value. Add the following code manually to the `Configure` method: ```csharp services.ConfigureAll(myOptions => { myOptions.Option1 = "ConfigureAll replacement value"; }); ``` Running the sample app after adding the code produces the following result: ```html named_options_1: option1 = ConfigureAll replacement value, option2 = -1 named_options_2: option1 = ConfigureAll replacement value, option2 = 5 ``` > [!NOTE] > In ASP.NET Core 2.0 and later, all options are named instances. Existing `IConfigureOption` instances are treated as targeting the `Options.DefaultName` instance, which is `string.Empty`. `IConfigureNamedOptions` also implements `IConfigureOptions`. The default implementation of the [IOptionsFactory<TOptions>](/dotnet/api/microsoft.extensions.options.ioptionsfactory-1) ([reference source](https://github.com/aspnet/Options/blob/release/2.0/src/Microsoft.Extensions.Options/IOptionsFactory.cs) has logic to use each appropriately. The `null` named option is used to target all of the named instances instead of a specific named instance ([ConfigureAll](/dotnet/api/microsoft.extensions.dependencyinjection.optionsservicecollectionextensions.configureall) and [PostConfigureAll](/dotnet/api/microsoft.extensions.dependencyinjection.optionsservicecollectionextensions.postconfigureall) use this convention). ## IPostConfigureOptions *Requires ASP.NET Core 2.0 or later.* Set postconfiguration with [IPostConfigureOptions<TOptions>](/dotnet/api/microsoft.extensions.options.ipostconfigureoptions-1). Postconfiguration runs after all [IConfigureOptions<TOptions>](/dotnet/api/microsoft.extensions.options.iconfigureoptions-1) configuration occurs: ```csharp services.PostConfigure(myOptions => { myOptions.Option1 = "post_configured_option1_value"; }); ``` [PostConfigure<TOptions>](/dotnet/api/microsoft.extensions.options.ipostconfigureoptions-1.postconfigure) is available to post-configure named options: ```csharp services.PostConfigure("named_options_1", myOptions => { myOptions.Option1 = "post_configured_option1_value"; }); ``` Use [PostConfigureAll<TOptions>](/dotnet/api/microsoft.extensions.dependencyinjection.optionsservicecollectionextensions.postconfigureall) to post-configure all named configuration instances: ```csharp services.PostConfigureAll("named_options_1", myOptions => { myOptions.Option1 = "post_configured_option1_value"; }); ``` ## Options factory, monitoring, and cache [IOptionsMonitor](/dotnet/api/microsoft.extensions.options.ioptionsmonitor-1) is used for notifications when `TOptions` instances change. `IOptionsMonitor` supports reloadable options, change notifications, and `IPostConfigureOptions`. [IOptionsFactory<TOptions>](/dotnet/api/microsoft.extensions.options.ioptionsfactory-1) (ASP.NET Core 2.0 or later) is responsible for creating new options instances. It has a single [Create](/dotnet/api/microsoft.extensions.options.ioptionsfactory-1.create) method. The default implementation takes all registered `IConfigureOptions` and `IPostConfigureOptions` and runs all the configures first, followed by the post-configures. It distinguishes between `IConfigureNamedOptions` and `IConfigureOptions` and only calls the appropriate interface. [IOptionsMonitorCache<TOptions>](/dotnet/api/microsoft.extensions.options.ioptionsmonitorcache-1) (ASP.NET Core 2.0 or later) is used by `IOptionsMonitor` to cache `TOptions` instances. The `IOptionsMonitorCache` invalidates options instances in the monitor so that the value is recomputed ([TryRemove](/dotnet/api/microsoft.extensions.options.ioptionsmonitorcache-1.tryremove)). Values can be manually introduced as well with [TryAdd](/dotnet/api/microsoft.extensions.options.ioptionsmonitorcache-1.tryadd). The [Clear](/dotnet/api/microsoft.extensions.options.ioptionsmonitorcache-1.clear) method is used when all named instances should be recreated on demand. ## Accessing options during startup `IOptions` can be used in `Configure`, since services are built before the `Configure` method executes. If a service provider is built in `ConfigureServices` to access options, it wouldn't contain any options configurations provided after the service provider is built. Therefore, an inconsistent options state may exist due to the ordering of service registrations. Since options are typically loaded from configuration, configuration can be used in startup in both `Configure` and `ConfigureServices`. For examples of using configuration during startup, see the [Application startup](xref:fundamentals/startup) topic. ## See also * [Configuration](xref:fundamentals/configuration/index)