Skip to content

Commit 98d7e82

Browse files
authored
Configuration article overhaul (#36239)
1 parent cb5af1f commit 98d7e82

26 files changed

Lines changed: 1534 additions & 2772 deletions

aspnetcore/fundamentals/configuration/index.md

Lines changed: 1271 additions & 520 deletions
Large diffs are not rendered by default.

aspnetcore/fundamentals/configuration/index/includes/index3-5.md

Lines changed: 0 additions & 288 deletions
This file was deleted.

aspnetcore/fundamentals/configuration/index/includes/index6.md

Lines changed: 0 additions & 939 deletions
This file was deleted.

aspnetcore/fundamentals/configuration/index/includes/index7.md

Lines changed: 0 additions & 944 deletions
This file was deleted.

aspnetcore/fundamentals/configuration/options.md

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,15 @@ description: Discover how to use the options pattern to represent groups of rela
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: tdykstra
77
ms.custom: mvc
8-
ms.date: 04/20/2025
8+
ms.date: 01/15/2026
99
uid: fundamentals/configuration/options
1010
---
1111
# Options pattern in ASP.NET Core
1212

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

15-
<!-- Update [!INCLUDE[](~/includes/bind7.md)]
16-
when updating this article -->
17-
1815
:::moniker range=">= aspnetcore-7.0"
1916

20-
By [Rick Anderson](https://twitter.com/RickAndMSFT).
21-
2217
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:
2318

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

3530
## Bind hierarchical configuration
3631

37-
[!INCLUDE[](~/includes/bind7.md)]
32+
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:
33+
34+
```json
35+
"Position": {
36+
"Title": "Editor",
37+
"Name": "Joe Smith"
38+
}
39+
```
40+
41+
Create the following `PositionOptions` class:
42+
43+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/PositionOptions.cs?name=snippet)]
44+
45+
An options class:
46+
47+
* Must be non-abstract.
48+
* Has public read-write properties of the type that have corresponding items in config are bound.
49+
* Has its read-write properties bound to matching entries in configuration.
50+
* 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.
51+
52+
The following code:
53+
54+
* Calls [ConfigurationBinder.Bind](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind*) to bind the `PositionOptions` class to the `Position` section.
55+
* Displays the `Position` configuration data.
56+
57+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test22.cshtml.cs?name=snippet)]
58+
59+
In the preceding code, by default, changes to the JSON configuration file after the app has started are read.
60+
61+
[`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:
62+
63+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test21.cshtml.cs?name=snippet)]
64+
65+
In the preceding code, by default, changes to the JSON configuration file after the app has started are read.
66+
67+
Bind also allows the concretion of an abstract class. Consider the following code which uses the abstract class `SomethingWithAName`:
68+
69+
[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Options/NameTitleOptions.cs)]
70+
71+
The following code displays the `NameTitleOptions` configuration values:
72+
73+
[!code-csharp[](~/fundamentals/configuration/index/samples/8.x/ConfigSample/Pages/Test33.cshtml.cs?name=snippet)]
74+
75+
Calls to `Bind` are less strict than calls to `Get<>`:
76+
77+
* `Bind` allows the concretion of an abstract.
78+
* `Get<>` has to create an instance itself.
79+
80+
## The Options Pattern
81+
82+
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:
83+
84+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet)]
85+
86+
Using the preceding code, the following code reads the position options:
87+
88+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test2.cshtml.cs?name=snippet)]
89+
90+
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).
3891

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

aspnetcore/fundamentals/configuration/options/includes/options6.md

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
:::moniker range="= aspnetcore-6.0"
22

3-
By [Kirk Larkin](https://twitter.com/serpent5) and [Rick Anderson](https://twitter.com/RickAndMSFT).
4-
53
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:
64

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

1816
## Bind hierarchical configuration
1917

20-
[!INCLUDE[](~/includes/bind6.md)]
18+
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:
19+
20+
```json
21+
"Position": {
22+
"Title": "Editor",
23+
"Name": "Joe Smith"
24+
}
25+
```
26+
27+
Create the following `PositionOptions` class:
28+
29+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Options/PositionOptions.cs?name=snippet)]
30+
31+
An options class:
32+
33+
* Must be non-abstract with a public parameterless constructor.
34+
* All public read-write properties of the type are bound.
35+
* 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.
36+
37+
The following code:
38+
39+
* Calls [ConfigurationBinder.Bind](xref:Microsoft.Extensions.Configuration.ConfigurationBinder.Bind*) to bind the `PositionOptions` class to the `Position` section.
40+
* Displays the `Position` configuration data.
41+
42+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test22.cshtml.cs?name=snippet)]
43+
44+
In the preceding code, by default, changes to the JSON configuration file after the app has started are read.
45+
46+
[`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:
47+
48+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test21.cshtml.cs?name=snippet)]
49+
50+
In the preceding code, by default, changes to the JSON configuration file after the app has started are read.
51+
52+
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:
53+
54+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Program.cs?name=snippet)]
55+
56+
Using the preceding code, the following code reads the position options:
57+
58+
[!code-csharp[](~/fundamentals/configuration/index/samples/6.x/ConfigSample/Pages/Test2.cshtml.cs?name=snippet)]
59+
60+
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).
2161

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

aspnetcore/fundamentals/dependency-injection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ The following code is generated by the Razor Pages template using individual acc
105105

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

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

110110
## Service lifetimes
111111

aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-5-7.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ The following code is generated by the Razor Pages template using individual use
9595

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

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

100100
## Service lifetimes
101101

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

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

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

490490
## Service lifetimes
491491

aspnetcore/fundamentals/dependency-injection/includes/dependency-injection-8.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ The following code is generated by the Razor Pages template using individual acc
9696

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

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

101101
## Service lifetimes
102102

aspnetcore/fundamentals/host/generic-host.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ To set this value, use the environment variable or configure `HostOptions`. The
207207

208208
### Disable app configuration reload on change
209209

210-
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`.
210+
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`.
211211

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

676676
### Disable app configuration reload on change
677677

678-
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`.
678+
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`.
679679

680680
**Key**: `hostBuilder:reloadConfigOnChange`
681681
**Type**: `bool` (`true` or `false`)

0 commit comments

Comments
 (0)