This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can trysigning in orchanging directories.
Access to this page requires authorization. You can trychanging directories.
Configuration in .NET is performed using one or moreconfiguration providers. Configuration providers read configuration data from key-value pairs using various configuration sources:
Note
For information about configuring the .NET runtime itself, see.NET Runtime configuration settings.
Given one or more configuration sources, theIConfiguration type provides a unified view of the configuration data. Configuration is read-only, and the configuration pattern isn't designed to be programmatically writable. TheIConfiguration interface is a single representation of all the configuration sources, as shown in the following diagram:
.NET console applications created using thedotnet new command template or Visual Studio by defaultdon't expose configuration capabilities. To add configuration in a new .NET console application,add a package reference toMicrosoft.Extensions.Configuration. This package is the foundation for configuration in .NET apps. It provides theConfigurationBuilder and related types.
using Microsoft.Extensions.Configuration;var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary<string, string?>() { ["SomeKey"] = "SomeValue" }) .Build();Console.WriteLine(configuration["SomeKey"]);// Outputs:// SomeValueThe preceding code:
SomeKey key to the console.While this example uses an in-memory configuration, there are many configuration providers available, exposing functionality for file-based, environment variables, command line arguments, and other configuration sources. For more information, seeConfiguration providers in .NET.
Commonly, your apps will do more than just read configuration. They'll likely use dependency injection, logging, and other services. The.NET Generic Host approach is recommended for apps that use these services. Instead, consideradding a package reference toMicrosoft.Extensions.Hosting. Modify theProgram.cs file to match the following code:
using Microsoft.Extensions.Hosting;using IHost host = Host.CreateApplicationBuilder(args).Build();// Application code should start here.await host.RunAsync();TheHost.CreateApplicationBuilder(String[]) method provides default configuration for the app in the following order, from highest to lowest priority:
Development environment.Environment.json using theJSON configuration provider. For example,appsettings.Production.json andappsettings.Development.json.IConfiguration as a source.Adding a configuration provider overrides previous configuration values. For example, theCommand-line configuration provider overrides all values from other providers because it's added last. IfSomeKey is set in bothappsettings.json and the environment, the environment value is used because it was added afterappsettings.json.
One of the key advantages of using the .NET configuration abstractions is the ability to bind configuration values to instances of .NET objects. For example, the JSON configuration provider can be used to mapappsettings.json files to .NET objects and is used withdependency injection. This enables theoptions pattern, which uses classes to provide strongly typed access to groups of related settings. The default binder is reflection-based, but there's asource generator alternative that's easy to enable.
.NET configuration provides various abstractions. Consider the following interfaces:
IConfiguration hierarchy.These abstractions are agnostic to their underlying configuration provider (IConfigurationProvider). In other words, you can use anIConfiguration instance to access any configuration value from multiple providers.
The binder can use different approaches to process configuration values:
Note
The binder has a few limitations:
Configuration values can contain hierarchical data. Hierarchical objects are represented with the use of the: delimiter in the configuration keys. To access a configuration value, use the: character to delimit a hierarchy. For example, consider the following configuration values:
{ "Parent": { "FavoriteNumber": 7, "Child": { "Name": "Example", "GrandChild": { "Age": 3 } } }}The following table represents example keys and their corresponding values for the preceding example JSON:
| Key | Value |
|---|---|
"Parent:FavoriteNumber" | 7 |
"Parent:Child:Name" | "Example" |
"Parent:Child:GrandChild:Age" | 3 |
To access configuration values in their basic form, without the assistance of thegeneric host approach, use theConfigurationBuilder type directly.
Tip
TheSystem.Configuration.ConfigurationBuilder type is different to theMicrosoft.Extensions.Configuration.ConfigurationBuilder type. All of this content is specific to theMicrosoft.Extensions.* NuGet packages and namespaces.
Consider the following C# project:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>true</ImplicitUsings> </PropertyGroup> <ItemGroup> <Content Include="appsettings.json"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.0" /> </ItemGroup></Project>The preceding project file references several configuration NuGet packages:
Microsoft.Extensions.Configuration.Microsoft.Extensions.Configuration.Microsoft.Extensions.Configuration.Consider an exampleappsettings.json file:
{ "Settings": { "KeyOne": 1, "KeyTwo": true, "KeyThree": { "Message": "Oh, that's nice...", "SupportedVersions": { "v1": "1.0.0", "v3": "3.0.7" } }, "IPAddressRange": [ "46.36.198.121", "46.36.198.122", "46.36.198.123", "46.36.198.124", "46.36.198.125" ] }}Now, given this JSON file, here's an example consumption pattern using the configuration builder directly:
using Microsoft.Extensions.Configuration;// Build a config object, using env vars and JSON providers.IConfigurationRoot config = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .AddEnvironmentVariables() .Build();// Get values from the config given their key and their target type.Settings? settings = config.GetRequiredSection("Settings").Get<Settings>();// Write the values to the console.Console.WriteLine($"KeyOne = {settings?.KeyOne}");Console.WriteLine($"KeyTwo = {settings?.KeyTwo}");Console.WriteLine($"KeyThree:Message = {settings?.KeyThree?.Message}");// Application code which might rely on the config could start here.// This will output the following:// KeyOne = 1// KeyTwo = True// KeyThree:Message = Oh, that's nice...The preceding C# code:
"appsettings.json" file to be recognized by the JSON configuration provider."Settings" section and the correspondingSettings instance by using theconfig instance.TheSettings object is shaped as follows:
public sealed class Settings{ public required int KeyOne { get; set; } public required bool KeyTwo { get; set; } public required NestedSettings KeyThree { get; set; } = null!;}public sealed class NestedSettings{ public required string Message { get; set; } = null!;}To access theIConfiguration value, you can rely again on theMicrosoft.Extensions.Hosting NuGet package. Create a new console application, and paste the following project file contents into it:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>true</ImplicitUsings> </PropertyGroup> <ItemGroup> <Content Include="appsettings.json"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" /> </ItemGroup></Project>The preceding project file defines that:
Microsoft.Extensions.Hosting NuGet package reference is added.Add theappsettings.json file at the root of the project with the following contents:
{ "KeyOne": 1, "KeyTwo": true, "KeyThree": { "Message": "Thanks for checking this out!" }}Replace the contents of theProgram.cs file with the following C# code:
using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using IHost host = Host.CreateApplicationBuilder(args).Build();// Ask the service provider for the configuration abstraction.IConfiguration config = host.Services.GetRequiredService<IConfiguration>();// Get values from the config given their key and their target type.int keyOneValue = config.GetValue<int>("KeyOne");bool keyTwoValue = config.GetValue<bool>("KeyTwo");string? keyThreeNestedValue = config.GetValue<string>("KeyThree:Message");// Write the values to the console.Console.WriteLine($"KeyOne = {keyOneValue}");Console.WriteLine($"KeyTwo = {keyTwoValue}");Console.WriteLine($"KeyThree:Message = {keyThreeNestedValue}");// Application code which might rely on the config could start here.await host.RunAsync();// This will output the following:// KeyOne = 1// KeyTwo = True// KeyThree:Message = Thanks for checking this out!When you run this application, theHost.CreateApplicationBuilder defines the behavior to discover the JSON configuration and expose it through theIConfiguration instance. From thehost instance, you can ask the service provider for theIConfiguration instance and then ask it for values.
Tip
Using the rawIConfiguration instance in this way, while convenient, doesn't scale very well. When applications grow in complexity, and their corresponding configurations become more complex, we recommend that you use theoptions pattern as an alternative.
Consider the sameappsettings.json file contents from the previous example:
{ "SupportedVersions": { "v1": "1.0.0", "v3": "3.0.7" }, "IPAddressRange": [ "46.36.198.123", "46.36.198.124", "46.36.198.125" ]}Replace the contents of theProgram.cs file with the following C# code:
using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using IHost host = Host.CreateApplicationBuilder(args).Build();// Ask the service provider for the configuration abstraction.IConfiguration config = host.Services.GetRequiredService<IConfiguration>();// Get values from the config given their key and their target type.string? ipOne = config["IPAddressRange:0"];string? ipTwo = config["IPAddressRange:1"];string? ipThree = config["IPAddressRange:2"];string? versionOne = config["SupportedVersions:v1"];string? versionThree = config["SupportedVersions:v3"];// Write the values to the console.Console.WriteLine($"IPAddressRange:0 = {ipOne}");Console.WriteLine($"IPAddressRange:1 = {ipTwo}");Console.WriteLine($"IPAddressRange:2 = {ipThree}");Console.WriteLine($"SupportedVersions:v1 = {versionOne}");Console.WriteLine($"SupportedVersions:v3 = {versionThree}");// Application code which might rely on the config could start here.await host.RunAsync();// This will output the following:// IPAddressRange:0 = 46.36.198.123// IPAddressRange:1 = 46.36.198.124// IPAddressRange:2 = 46.36.198.125// SupportedVersions:v1 = 1.0.0// SupportedVersions:v3 = 3.0.7The values are accessed using the indexer API where each key is a string, and the value is a string. Configuration supports properties, objects, arrays, and dictionaries.
The following table shows the configuration providers available to .NET Core apps.
| Provider | Provides configuration from |
|---|---|
| Azure App configuration provider | Azure App Configuration |
| Azure Key Vault configuration provider | Azure Key Vault |
| Command-line configuration provider | Command-line parameters |
| Custom configuration provider | Custom source |
| Environment Variables configuration provider | Environment variables |
| File configuration provider | JSON, XML, and INI files |
| Key-per-file configuration provider | Directory files |
| Memory configuration provider | In-memory collections |
| App secrets (Secret Manager) | File in the user profile directory |
Tip
The order in which configuration providers are added matters. When multiple configuration providers are used and more than one provider specifies the same key, the last one added is used.
For more information on various configuration providers, seeConfiguration providers in .NET.
Was this page helpful?
Need help with this topic?
Want to try using Ask Learn to clarify or guide you through this topic?
Was this page helpful?
Want to try using Ask Learn to clarify or guide you through this topic?