Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,806 changes: 1,286 additions & 520 deletions aspnetcore/fundamentals/configuration/index.md

Large diffs are not rendered by default.

288 changes: 0 additions & 288 deletions aspnetcore/fundamentals/configuration/index/includes/index3-5.md

This file was deleted.

939 changes: 0 additions & 939 deletions aspnetcore/fundamentals/configuration/index/includes/index6.md

This file was deleted.

944 changes: 0 additions & 944 deletions aspnetcore/fundamentals/configuration/index/includes/index7.md

This file was deleted.

67 changes: 60 additions & 7 deletions aspnetcore/fundamentals/configuration/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ description: Discover how to use the options pattern to represent groups of rela
monikerRange: '>= aspnetcore-3.1'
ms.author: tdykstra
ms.custom: mvc
ms.date: 04/20/2025
ms.date: 10/15/2025
uid: fundamentals/configuration/options
---
# Options pattern in ASP.NET Core

[!INCLUDE[](~/includes/not-latest-version.md)]

<!-- Update [!INCLUDE[](~/includes/bind7.md)]
when updating this article -->

:::moniker range=">= aspnetcore-7.0"

By [Rick Anderson](https://twitter.com/RickAndMSFT).

The options pattern uses classes to provide strongly typed access to groups of related settings. When [configuration settings](xref:fundamentals/configuration/index) are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

* [Encapsulation](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#encapsulation):
Expand All @@ -34,7 +29,65 @@ This article provides information on the options pattern in ASP.NET Core. For in

## Bind hierarchical configuration

[!INCLUDE[](~/includes/bind7.md)]
The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For example, to read the following configuration values:

```json
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
```

Create the following `PositionOptions` class:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/PositionOptions.cs?name=snippet)]

An options class:

* Must be non-abstract.
* Has public read-write properties of the type that have corresponding items in config are bound.
* Has its read-write properties bound to matching entries in configuration.
* Does ***not*** have its fields bound. In the preceding code, `Position` is not bound. The `Position` field is used so the string `"Position"` doesn't need to be hard coded in the app when binding the class to a configuration provider.

The following code:

* Calls [ConfigurationBinder.Bind](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind*) to bind the `PositionOptions` class to the `Position` section.
* Displays the `Position` configuration data.

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test22.cshtml.cs?name=snippet)]

In the preceding code, by default, changes to the JSON configuration file after the app has started are read.

[`ConfigurationBinder.Get<T>`](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Get*) binds and returns the specified type. `ConfigurationBinder.Get<T>` may be more convenient than using `ConfigurationBinder.Bind`. The following code shows how to use `ConfigurationBinder.Get<T>` with the `PositionOptions` class:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test21.cshtml.cs?name=snippet)]

In the preceding code, by default, changes to the JSON configuration file after the app has started are read.

Bind also allows the concretion of an abstract class. Consider the following code which uses the abstract class `SomethingWithAName`:

[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs)]

The following code displays the `NameTitleOptions` configuration values:

[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs?name=snippet)]

Calls to `Bind` are less strict than calls to `Get<>`:

* `Bind` allows the concretion of an abstract.
* `Get<>` has to create an instance itself.

## The Options Pattern

An alternative approach when using the ***options pattern*** is to bind the `Position` section and add it to the [dependency injection service container](xref:fundamentals/dependency-injection). In the following code, `PositionOptions` is added to the service container with <xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure*> and bound to configuration:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet)]

Using the preceding code, the following code reads the position options:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test2.cshtml.cs?name=snippet)]

In the preceding code, changes to the JSON configuration file after the app has started are ***not*** read. To read changes after the app has started, use [IOptionsSnapshot](xref:fundamentals/configuration/options#ios).

<a name="oi"></a>

Expand Down
46 changes: 43 additions & 3 deletions aspnetcore/fundamentals/configuration/options/includes/options6.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
:::moniker range="= aspnetcore-6.0"

By [Kirk Larkin](https://twitter.com/serpent5) and [Rick Anderson](https://twitter.com/RickAndMSFT).

The options pattern uses classes to provide strongly typed access to groups of related settings. When [configuration settings](xref:fundamentals/configuration/index) are isolated by scenario into separate classes, the app adheres to two important software engineering principles:

* [Encapsulation](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#encapsulation):
Expand All @@ -17,7 +15,49 @@ This article provides information on the options pattern in ASP.NET Core. For in

## Bind hierarchical configuration

[!INCLUDE[](~/includes/bind6.md)]
The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For example, to read the following configuration values:

```json
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
```

Create the following `PositionOptions` class:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/PositionOptions.cs?name=snippet)]

An options class:

* Must be non-abstract with a public parameterless constructor.
* All public read-write properties of the type are bound.
* Fields are ***not*** bound. In the preceding code, `Position` is not bound. The `Position` field is used so the string `"Position"` doesn't need to be hard coded in the app when binding the class to a configuration provider.

The following code:

* Calls [ConfigurationBinder.Bind](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind*) to bind the `PositionOptions` class to the `Position` section.
* Displays the `Position` configuration data.

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test22.cshtml.cs?name=snippet)]

In the preceding code, by default, changes to the JSON configuration file after the app has started are read.

[`ConfigurationBinder.Get<T>`](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Get*) binds and returns the specified type. `ConfigurationBinder.Get<T>` may be more convenient than using `ConfigurationBinder.Bind`. The following code shows how to use `ConfigurationBinder.Get<T>` with the `PositionOptions` class:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test21.cshtml.cs?name=snippet)]

In the preceding code, by default, changes to the JSON configuration file after the app has started are read.

An alternative approach when using the ***options pattern*** is to bind the `Position` section and add it to the [dependency injection service container](xref:fundamentals/dependency-injection). In the following code, `PositionOptions` is added to the service container with <xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure*> and bound to configuration:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet)]

Using the preceding code, the following code reads the position options:

[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test2.cshtml.cs?name=snippet)]

In the preceding code, changes to the JSON configuration file after the app has started are ***not*** read. To read changes after the app has started, use [IOptionsSnapshot](xref:fundamentals/configuration/options#ios).

<a name="oi"></a>

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/fundamentals/dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ The following code is generated by the Razor Pages template using individual acc

[!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/ProgramEF.cs?name=snippet)]

[!INCLUDE[](~/includes/combine-di6.md)]
[!INCLUDE[](~/includes/combine-service-collection-60-or-later.md)]

## Service lifetimes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ The following code is generated by the Razor Pages template using individual use

[!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/ProgramEF.cs?name=snippet)]

[!INCLUDE[](~/includes/combine-di6.md)]
[!INCLUDE[](~/includes/combine-service-collection-60-or-later.md)]

## Service lifetimes

Expand Down Expand Up @@ -485,7 +485,7 @@ The following code is generated by the Razor Pages template using individual use

[!code-csharp[](~/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/StartupEF.cs?name=snippet)]

[!INCLUDE[](~/includes/combine-di.md)]
[!INCLUDE[](~/includes/combine-service-collection-31-to-60.md)]

## Service lifetimes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ The following code is generated by the Razor Pages template using individual acc

[!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/ProgramEF.cs?name=snippet)]

[!INCLUDE[](~/includes/combine-di6.md)]
[!INCLUDE[](~/includes/combine-service-collection-60-or-later.md)]

## Service lifetimes

Expand Down
4 changes: 2 additions & 2 deletions aspnetcore/fundamentals/host/generic-host.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ To set this value, use the environment variable or configure `HostOptions`. The

### Disable app configuration reload on change

By [default](xref:fundamentals/configuration/index#default), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`.
By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`.

**Key**: `hostBuilder:reloadConfigOnChange`
**Type**: `bool` (`true` or `false`)
Expand Down Expand Up @@ -675,7 +675,7 @@ To set this value, use the environment variable or configure `HostOptions`. The

### Disable app configuration reload on change

By [default](xref:fundamentals/configuration/index#default), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`.
By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), `appsettings.json` and `appsettings.{Environment}.json` are reloaded when the file changes. To disable this reload behavior in .NET 5 or later, set the `hostBuilder:reloadConfigOnChange` key to `false`.

**Key**: `hostBuilder:reloadConfigOnChange`
**Type**: `bool` (`true` or `false`)
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/fundamentals/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ For more information, see <xref:fundamentals/servers/index>.

ASP.NET Core provides a [configuration](xref:fundamentals/configuration/index) framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources.

By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.
By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.

For managing confidential configuration data such as passwords in the development environment, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration).

Expand Down
6 changes: 3 additions & 3 deletions aspnetcore/fundamentals/index/includes/index3-7.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ For more information, see <xref:fundamentals/servers/index>.

ASP.NET Core provides a [configuration](xref:fundamentals/configuration/index) framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources.

By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.
By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.

For managing confidential configuration data such as passwords, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration).

Expand Down Expand Up @@ -321,9 +321,9 @@ For more information, see <xref:fundamentals/servers/index>.

ASP.NET Core provides a configuration framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources.

By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.
By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.

The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For more information, see [Bind hierarchical configuration data using the options pattern](xref:fundamentals/configuration/index#optpat).
The preferred way to read related configuration values is using the [options pattern](xref:fundamentals/configuration/options). For more information, see [Bind hierarchical configuration data using the options pattern](xref:fundamentals/configuration/index#bind-hierarchical-configuration-data-using-the-options-pattern).

For managing confidential configuration data such as passwords, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration).

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/fundamentals/index/includes/index8.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ For more information, see <xref:fundamentals/servers/index>.

ASP.NET Core provides a [configuration](xref:fundamentals/configuration/index) framework that gets settings as name-value pairs from an ordered set of configuration providers. Built-in configuration providers are available for a variety of sources, such as `.json` files, `.xml` files, environment variables, and command-line arguments. Write custom configuration providers to support other sources.

By [default](xref:fundamentals/configuration/index#default), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.
By [default](xref:fundamentals/configuration/index#default-app-configuration-sources), ASP.NET Core apps are configured to read from `appsettings.json`, environment variables, the command line, and more. When the app's configuration is loaded, values from environment variables override values from `appsettings.json`.

For managing confidential configuration data such as passwords, .NET provides the [Secret Manager](xref:security/app-secrets#secret-manager). For production secrets, we recommend [Azure Key Vault](xref:security/key-vault-configuration).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The following command makes the app respond to port `7777`:
dotnet run --urls="https://localhost:7777"
```

If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel)
If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration)

#### Read the port from environment

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The following command makes the app respond to port `7777`:
dotnet run --urls="https://localhost:7777"
```

If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel)
If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration)

#### Read the port from environment

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The following command makes the app respond to port `7777`:
dotnet run --urls="https://localhost:7777"
```

If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel)
If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration)

#### Read the port from environment

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The following command makes the app respond to port `7777`:
dotnet run --urls="https://localhost:7777"
```

If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel)
If the Kestrel endpoint is also configured in the `appsettings.json` file, the `appsettings.json` file specified URL is used. For more information, see [Kestrel endpoint configuration](xref:fundamentals/configuration/index#kestrel-endpoint-configuration)

#### Read the port from environment

Expand Down
Loading