.NET의 구성은 하나 이상의구성 공급자를 사용하여 수행됩니다. 구성 공급자는 다양한 구성 원본을 사용하여 키-값 쌍에서 구성 데이터를 읽습니다.
- 설정 파일(예: appsettings.json
- 환경 변수
- Azure Key Vault
- Azure 앱 구성
- 명령줄 인수
- 사용자 지정 공급자(설치 또는 생성)
- 디렉터리 파일
- 메모리 내 .NET 개체
- 타사 공급자
메모
.NET 런타임 자체를 구성하는 방법에 대한 자세한 내용은 .NET 런타임 구성 설정참조하세요.
개념 및 추상화
하나 이상의 구성 원본이 지정된 경우 IConfiguration 형식은 구성 데이터의 통합 보기를 제공합니다. 구성은 읽기 전용이며 구성 패턴은 프로그래밍 방식으로 쓰기 가능하도록 설계되지 않았습니다.
IConfiguration 인터페이스는 다음 다이어그램과 같이 모든 구성 원본의 단일 표현입니다.
콘솔 앱 구성
dotnet 새 명령 템플릿 또는 Visual Studio를 사용하여 만든 .NET 콘솔 앱은 기본적으로 구성 기능을 노출하지 않습니다. 새 .NET 콘솔 애플리케이션에서 구성을 추가하려면 Microsoft.Extensions.Configuration에 패키지 참조를📦 추가합니다. 이 패키지는 .NET 앱에서 구성을 위한 기초입니다. ConfigurationBuilder 및 관련 형식을 제공합니다.
using Microsoft.Extensions.Configuration;
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>()
{
["SomeKey"] = "SomeValue"
})
.Build();
Console.WriteLine(configuration["SomeKey"]);
// Outputs:
// SomeValue
앞의 코드는 다음과 같습니다.
- 새 ConfigurationBuilder 인스턴스를 만듭니다.
- 구성 작성기에서 키-값 쌍의 메모리 내 컬렉션을 추가합니다.
- Build() 메서드를 호출하여 IConfiguration 인스턴스를 만듭니다.
-
SomeKey키의 값을 콘솔에 씁니다.
이 예제에서는 메모리 내 구성을 사용하지만 파일 기반, 환경 변수, 명령줄 인수 및 기타 구성 원본에 대한 기능을 노출하는 많은 구성 공급자를 사용할 수 있습니다. 자세한 내용은 .NET 구성 공급자를 참조하세요.
대체 호스팅 방법
일반적으로 앱은 구성을 읽는 것 이상의 작업을 수행합니다. 종속성 주입, 로깅 및 기타 서비스를 사용할 가능성이 높습니다. 이러한 서비스를 사용하는 앱에는 .NET 제네릭 호스트 방법을 사용하는 것이 좋습니다. 대신 Microsoft.Extensions.Hosting에 패키지 참조를 추가하는 것이 📦좋습니다. 다음 코드와 일치하도록 Program.cs 파일을 수정합니다.
using Microsoft.Extensions.Hosting;
using IHost host = Host.CreateApplicationBuilder(args).Build();
// Application code should start here.
await host.RunAsync();
Host.CreateApplicationBuilder(String[]) 메서드는 가장 높은 우선 순위에서 가장 낮은 우선 순위까지 다음 순서로 앱에 대한 기본 구성을 제공합니다.
- 명령줄 인수는 명령줄 구성 공급자를 사용하여에서 제공합니다.
- 환경 변수 구성 공급자를 통해 설정되는 환경 변수.
- .
-
appsettings.
Environment을 JSON 구성 공급자를 사용하여. 예를 들어 appsettings.생산.json 및 appsettings.개발.json. - JSON 구성 공급자사용하여 appsettings.json.
-
ChainedConfigurationProvider: 기존
IConfiguration를 원본으로 추가합니다.
구성 공급자를 추가하면 이전 구성 값이 재정의됩니다. 예를 들어 명령줄 구성 공급자 마지막으로 추가되었기 때문에 다른 공급자의 모든 값을 재정의합니다.
SomeKey
appsettings.json 환경 모두에서 설정된 경우 환경 값은 appsettings.json후에 추가되었기 때문에 사용됩니다.
바인딩
.NET 구성 추상화 사용의 주요 이점 중 하나는 구성 값을 .NET 개체의 인스턴스에 바인딩 하는 기능입니다. 예를 들어 JSON 구성 공급자는 appsettings.json 파일을 .NET 개체에 매핑하는 데 사용할 수 있으며 종속성 주입함께 사용됩니다. 이렇게 하면 클래스를 사용하여 관련 설정 그룹에 강력한 형식의 액세스를 제공하는 옵션 패턴사용할 수 있습니다. 기본 바인더는 리플렉션 기반이지만, 쉽게 활성화할 수 있는 원본 생성기 대체이 있습니다.
.NET 구성은 다양한 추상화 기능을 제공합니다. 다음 인터페이스를 고려합니다.
- IConfiguration: 키/값 애플리케이션 구성 속성 집합을 나타냅니다.
-
IConfigurationRoot:
IConfiguration계층의 루트를 나타냅니다. - IConfigurationSection: 애플리케이션 구성 값의 섹션을 나타냅니다.
이러한 추상화는 기본 구성 공급자(IConfigurationProvider)와 관련이 없습니다. 즉, IConfiguration 인스턴스를 사용하여 여러 공급자의 구성 값에 액세스할 수 있습니다.
바인더는 다양한 방법을 사용하여 구성 값을 처리할 수 있습니다.
- 기본 제공 변환기를 사용한 원시 타입의 직접 역직렬화
- 복합 형식에 유형이 하나 있을 때의 TypeConverter.
- 속성이 있는 복합 형식에 대한 리플렉션입니다.
메모
바인더에는 몇 가지 제한 사항이 있습니다.
- 속성은 프라이빗 setter가 있거나 해당 형식을 변환할 수 없는 경우 무시됩니다.
- 해당 구성 키가 없는 속성은 무시됩니다.
바인딩 계층 구조
구성 값은 계층적 데이터를 포함할 수 있습니다. 계층적 개체는 구성 키에서 : 구분 기호를 사용하여 표시됩니다. 구성 값에 액세스하려면 : 문자를 사용하여 계층을 구분합니다. 예를 들어 다음 구성 값을 고려합니다.
{
"Parent": {
"FavoriteNumber": 7,
"Child": {
"Name": "Example",
"GrandChild": {
"Age": 3
}
}
}
}
다음 표에서는 앞의 예제 JSON에 대한 예제 키와 해당 값을 나타냅니다.
| 열쇠 | 값 |
|---|---|
"Parent:FavoriteNumber" |
7 |
"Parent:Child:Name" |
"Example" |
"Parent:Child:GrandChild:Age" |
3 |
고급 바인딩 시나리오
구성 바인더에는 특정 형식으로 작업할 때 특정 동작 및 제한 사항이 있습니다. 이 섹션에는 다음 하위 섹션이 포함되어 있습니다.
딕셔너리에 바인딩
값이 변경 가능한 컬렉션 형식(예: 배열 또는 목록)인 위치에 구성 Dictionary<TKey,TValue> 을 바인딩하는 경우 동일한 키에 대한 반복 바인딩은 컬렉션 값을 바꾸는 대신 확장합니다.
다음 예제에서는 이 동작을 보여 줍니다.
IConfiguration config = new ConfigurationBuilder()
.AddInMemoryCollection()
.Build();
config["Queue:0"] = "Value1";
var dict = new Dictionary<string, string[]>() { { "Queue", new[] { "InitialValue" } } };
Console.WriteLine("=== Dictionary Binding with Collection Values ===");
Console.WriteLine($"Initially: {string.Join(", ", dict["Queue"])}");
// In .NET 7+, binding extends the collection instead of replacing it.
config.Bind(dict);
Console.WriteLine($"After Bind: {string.Join(", ", dict["Queue"])}");
config["Queue:1"] = "Value2";
config.Bind(dict);
Console.WriteLine($"After 2nd Bind: {string.Join(", ", dict["Queue"])}");
자세한 내용은 구성을 사전에 바인딩하여 값을 확장하는 방법을 참조하십시오.
콜론이 있는 사전 키
콜론(:) 문자는 구성 키에서 계층 구분 기호로 예약됩니다. 즉, 구성을 바인딩할 때 사전 키에서 콜론을 사용할 수 없습니다. 키에 콜론(예: URL 또는 기타 형식 식별자)이 포함된 경우 구성 시스템은 이를 리터럴 문자가 아닌 계층 경로로 해석합니다. 다음 해결 방법을 고려합니다.
- 구성 키에서 대체 구분 기호 문자(예: 이중 밑줄
__)를 사용하고 필요한 경우 프로그래밍 방식으로 변환합니다. - System.Text.Json 또는 키에 콜론을 지원하는 유사한 라이브러리를 사용하여 구성을 원시 JSON으로 수동으로 역직렬화합니다.
- 콜론을 사용하여 안전한 키를 원하는 키로 변환하는 사용자 지정 매핑 계층을 만듭니다.
IReadOnly* 형식에 바인딩
구성 바인더는 IReadOnlyList<T> 및 IReadOnlyDictionary<TKey, TValue>와 같은 읽기 전용 컬렉션 인터페이스에 직접 바인딩하는 것을 지원하지 않습니다. 이러한 인터페이스에는 바인더가 컬렉션을 채우는 데 필요한 메커니즘이 부족합니다.
읽기 전용 컬렉션을 사용하려면 바인더가 채우는 속성에 변경 가능한 형식을 사용한 다음, 소비자를 위한 읽기 전용 인터페이스로 노출합니다.
Console.WriteLine("=== IReadOnly* Types (NOT Directly Supported) ===");
var readonlyConfig = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["Settings:Values:0"] = "Item1",
["Settings:Values:1"] = "Item2",
["Settings:Values:2"] = "Item3",
})
.Build();
// This class uses List<string> for binding, exposes as IReadOnlyList<string>.
var settings = new SettingsWithReadOnly();
readonlyConfig.GetSection("Settings").Bind(settings);
Console.WriteLine("Values bound to mutable List, exposed as IReadOnlyList:");
foreach (var value in settings.ValuesReadOnly)
{
Console.WriteLine($" {value}");
}
구성 클래스 구현:
class SettingsWithReadOnly
{
// Use mutable type for binding
public List<string> Values { get; set; } = [];
// Expose as read-only for consumers
public IReadOnlyList<string> ValuesReadOnly => Values;
}
이 접근 방식을 사용하면 바인더가 소비자에게 변경할 수 없는 IReadOnlyList<string> 인터페이스를 제공하는 동안 변경 가능한 List<string>를 구성할 수 있습니다.
매개 변수가 있는 생성자를 사용하여 바인딩
.NET 7부터 구성 바인더는 매개 변수가 있는 단일 공용 생성자를 사용하여 형식에 대한 바인딩을 지원합니다. 이렇게 하면 변경할 수 없는 형식 및 레코드를 구성에서 직접 채울 수 있습니다.
Console.WriteLine("=== Parameterized Constructor Binding ===");
var ctorConfig = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["AppSettings:Name"] = "MyApp",
["AppSettings:MaxConnections"] = "100",
["AppSettings:Timeout"] = "30"
})
.Build();
// Binding to a type with a single parameterized constructor
var appSettings = ctorConfig.GetSection("AppSettings").Get<AppSettings>();
if (appSettings != null)
{
Console.WriteLine($"Name: {appSettings.Name}");
Console.WriteLine($"MaxConnections: {appSettings.MaxConnections}");
Console.WriteLine($"Timeout: {appSettings.Timeout}");
}
변경할 수 없는 설정 클래스:
// Immutable type with single parameterized constructor.
class AppSettings
{
public string Name { get; }
public int MaxConnections { get; }
public int Timeout { get; }
public AppSettings(string name, int maxConnections, int timeout)
{
Name = name;
MaxConnections = maxConnections;
Timeout = timeout;
}
}
중요합니다
바인더는 매개 변수가 있는 단일 공용 생성자가 있는 형식만 지원합니다. 형식에 여러 공용 매개 변수가 있는 생성자가 있는 경우 바인더는 사용할 생성자를 결정할 수 없으며 바인딩이 실패합니다. 매개 변수가 있는 단일 생성자 또는 속성 setter와 함께 매개 변수가 없는 생성자를 사용합니다.
기본 예제
제네릭 호스트 접근 방식의 도움 없이 기본 형식의 구성 값에 액세스하려면 ConfigurationBuilder 형식을 직접 사용합니다.
팁
System.Configuration.ConfigurationBuilder 형식은 Microsoft.Extensions.Configuration.ConfigurationBuilder 형식과 다릅니다. 이 모든 콘텐츠는 Microsoft.Extensions.* NuGet 패키지 및 네임스페이스와 관련이 있습니다.
다음 C# 프로젝트를 고려합니다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.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.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.3" />
</ItemGroup>
</Project>
위의 프로젝트 파일은 다음과 같은 여러 구성 NuGet 패키지를 참조합니다.
- Microsoft.Extensions.Configuration.Binder: 을 위해 구성 공급자에서 개체를 데이터에 바인딩하는 기능입니다.
-
Microsoft.Extensions.Configuration.Json:
Microsoft.Extensions.Configuration대한 JSON 구성 공급자 구현입니다. -
Microsoft.Extensions.Configuration.EnvironmentVariables:
Microsoft.Extensions.Configuration대한 환경 변수 구성 공급자 구현입니다.
예제 appsettings.json 파일을 고려합니다.
{
"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"
]
}
}
이제 이 JSON 파일을 고려할 때 구성 작성기를 직접 사용하는 예제 소비 패턴은 다음과 같습니다.
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...
앞의 C# 코드는 다음과 같습니다.
- ConfigurationBuilder를 (하나의) 인스턴스화합니다.
- JSON 구성 공급자가 인식할
"appsettings.json"파일을 추가합니다. - 환경 변수 구성 공급자가 인식할 수 있는 환경 변수를 추가합니다.
-
"Settings"인스턴스를 사용하여 필요한Settings섹션 및 해당config인스턴스를 가져옵니다.
Settings 개체의 모양은 다음과 같습니다.
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!;
}
호스팅을 사용하여 기본 예제
IConfiguration 값에 액세스하려면 Microsoft.Extensions.Hosting NuGet 패키지를 다시 사용할 수 있습니다. 새 콘솔 애플리케이션을 만들고 다음 프로젝트 파일 내용을 붙여넣습니다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.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.3" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.3" />
</ItemGroup>
</Project>
위의 프로젝트 파일은 다음을 정의합니다.
- 애플리케이션이 실행 파일입니다.
- appsettings.json 파일은 프로젝트가 컴파일될 때 출력 디렉터리에 복사됩니다.
-
Microsoft.Extensions.HostingNuGet 패키지 참조가 추가됩니다.
다음 내용을 사용하여 프로젝트의 루트에 appsettings.json 파일을 추가합니다.
{
"KeyOne": 1,
"KeyTwo": true,
"KeyThree": {
"Message": "Thanks for checking this out!"
}
}
Program.cs 파일의 내용을 다음 C# 코드로 바꿉니다.
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!
이 애플리케이션을 실행할 때 Host.CreateApplicationBuilder JSON 구성을 검색하고 IConfiguration 인스턴스를 통해 노출하는 동작을 정의합니다.
host 인스턴스에서 서비스 공급자에게 IConfiguration 인스턴스를 요청한 다음 값을 요청할 수 있습니다.
팁
이러한 방식으로 원시 IConfiguration 인스턴스를 사용하면 편리하지만 크기가 잘 조정되지 않습니다. 애플리케이션의 복잡성이 증가하고 해당 구성이 더 복잡해지면 옵션 패턴 대신 사용하는 것이 좋습니다.
인덱서 API를 호스팅하고 사용하는 기본 예제
이전 예제와 동일한 appsettings.json 파일 내용을 고려합니다.
{
"SupportedVersions": {
"v1": "1.0.0",
"v3": "3.0.7"
},
"IPAddressRange": [
"46.36.198.123",
"46.36.198.124",
"46.36.198.125"
]
}
Program.cs 파일의 내용을 다음 C# 코드로 바꿉니다.
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.7
각 키가 문자열이고 값이 문자열인 인덱서 API를 사용하여 값에 액세스합니다. 구성은 속성, 개체, 배열 및 사전을 지원합니다.
구성 공급자
다음 표에서는 .NET Core 앱에서 사용할 수 있는 구성 공급자를 보여 줍니다.
| 구성 공급자 | 에서 구성을 제공합니다. |
|---|---|
| Azure 앱 구성 | Azure App Configuration (애저 앱 설정) |
| Azure Key Vault | Azure Key Vault (애저 키 볼트) |
| 명령줄 | 명령줄 매개 변수 |
| 사용자 지정 | 사용자 지정 원본 |
| 환경 변수 | 환경 변수 |
| 파일 | JSON, XML 및 INI 파일 |
| 파일당 키 | 디렉터리 파일 |
| 기억 | 메모리 내 컬렉션 |
| 앱 비밀(비밀 관리자) | 사용자 프로필 디렉터리의 파일 |
팁
구성 공급자가 추가되는 순서가 중요합니다. 여러 구성 공급자를 사용하고 둘 이상의 공급자가 동일한 키를 지정하는 경우 마지막으로 추가된 공급자가 사용됩니다.
다양한 구성 공급자에 대한 자세한 내용은 .NET 구성 공급자를 참조하세요.
또한 참고하세요
- .NET의 구성 공급자
- 사용자 지정 구성 공급자 구현
- 구성 버그를 github.com/dotnet/runtime 리포지토리에 만들어야 합니다.
- ASP.NET Core에서 구성
.NET