.NET의 구성 공급자

.NET에서 구성은 구성 공급자를 사용하여 수행할 수 있습니다. 여러 유형의 공급자는 다양한 구성 원본을 사용합니다. 이 문서에서는 모든 다양한 구성 공급자와 해당 소스를 자세히 설명합니다.

파일 구성 공급자

FileConfigurationProvider는 파일 시스템에서 구성을 로드하기 위한 기본 클래스입니다. 다음 구성 공급자는 FileConfigurationProvider에서 파생됩니다.

키는 대/소문자를 구분하지 않습니다. 모든 파일 구성 공급자는 단일 공급자에서 중복 키를 찾을 때 FormatException을 throw합니다.

JSON 구성 공급자

JsonConfigurationProvider 클래스는 JSON 파일에서 구성을 로드합니다. Microsoft.Extensions.Configuration.Json NuGet 패키지를 설치합니다.

오버로드는 다음을 지정할 수 있습니다.

  • 파일이 선택 사항인지 여부
  • 파일이 변경되면 구성을 다시 로드하는지 여부

다음 코드를 생각해 봅시다.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using ConsoleJson.Example;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

IHostEnvironment env = builder.Environment;

builder.Configuration
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);

TransientFaultHandlingOptions options = new();
builder.Configuration.GetSection(nameof(TransientFaultHandlingOptions))
    .Bind(options);

Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

앞의 코드가 하는 역할은 다음과 같습니다.

  • CreateApplicationBuilder(String[]) 메서드에 기본적으로 추가된 기존 구성 공급자를 모두 지웁니다.
  • 다음 옵션을 사용하여 appsettings.jsonappsettings.Environment.json 파일을 로드하도록 JSON 구성 공급자를 구성합니다.
    • optional: true: 파일은 선택 사항입니다.
    • reloadOnChange: true: 변경 내용이 저장되면 파일이 다시 로드됩니다.

Important

IConfigurationBuilder.Add구성 공급자를 추가할 때 추가된 구성 공급자가 IConfigurationSource 목록의 끝에 추가됩니다. 여러 공급자가 키를 찾은 경우 키를 읽는 마지막 공급자가 이전 공급자를 재정의합니다.

다양한 구성 설정을 사용하는 예제 appsettings.json 파일은 다음과 같습니다.

{
    "SecretKey": "Secret key value",
    "TransientFaultHandlingOptions": {
        "Enabled": true,
        "AutoRetryDelay": "00:00:07"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    }
}

구성 공급자가 추가된 후 IConfigurationBuilder 인스턴스에서 IConfigurationBuilder.Build()를 호출하여 IConfigurationRoot 개체를 가져올 수 있습니다. 구성 루트는 구성 계층 구조의 루트를 나타냅니다. 구성의 섹션은 .NET 개체의 인스턴스에 바인딩되고 나중에 IOptions<TOptions> 종속성 주입을 통해 제공될 수 있습니다.

참고 항목

JSON 파일의 빌드 작업출력 디렉터리에 복사 속성을 각각 콘텐츠새 버전이면 복사(또는 항상 복사)로 설정해야 합니다.

다음과 같이 정의된 TransientFaultHandlingOptions 클래스를 고려하세요.

namespace ConsoleJson.Example;

public sealed class TransientFaultHandlingOptions
{
    public bool Enabled { get; set; }
    public TimeSpan AutoRetryDelay { get; set; }
}

다음 코드는 구성 루트를 빌드하고, 섹션을 TransientFaultHandlingOptions 클래스 형식에 바인딩하고, 바인딩된 값을 콘솔 창에 출력합니다.

TransientFaultHandlingOptions options = new();
builder.Configuration.GetSection(nameof(TransientFaultHandlingOptions))
    .Bind(options);

Console.WriteLine($"TransientFaultHandlingOptions.Enabled={options.Enabled}");
Console.WriteLine($"TransientFaultHandlingOptions.AutoRetryDelay={options.AutoRetryDelay}");

애플리케이션은 다음 샘플 출력을 씁니다.

// Sample output:
//    TransientFaultHandlingOptions.Enabled=True
//    TransientFaultHandlingOptions.AutoRetryDelay=00:00:07

XML 구성 공급자

XmlConfigurationProvider 클래스는 런타임에 있는 XML 파일에서 구성을 로드합니다. Microsoft.Extensions.Configuration.Xml NuGet 패키지를 설치합니다.

다음 코드에서는 XML 구성 공급자를 사용한 XML 파일의 구성을 보여 줍니다.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

builder.Configuration
    .AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true)
    .AddXmlFile("repeating-example.xml", optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();

if (args is { Length: > 0 })
{
    builder.Configuration.AddCommandLine(args);
}

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

앞의 코드가 하는 역할은 다음과 같습니다.

  • CreateApplicationBuilder(String[]) 메서드에 기본적으로 추가된 기존 구성 공급자를 모두 지웁니다.
  • 다음 옵션을 사용하여 appsettings.xmlrepeating-example.xml 파일을 로드하도록 XML 구성 공급자를 구성합니다.
    • optional: true: 파일은 선택 사항입니다.
    • reloadOnChange: true: 변경 내용이 저장되면 파일이 다시 로드됩니다.
  • 환경 변수 구성 공급자를 구성합니다.
  • 지정된 args에 인수가 포함된 경우 명령줄 구성 공급자를 구성합니다.

XML 설정은 환경 변수 구성 공급자명령줄 구성 공급자의 설정에 따라 재정의됩니다.

다양한 구성 설정을 사용하는 예제 appsettings.xml 파일은 다음과 같습니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <SecretKey>Secret key value</SecretKey>
  <TransientFaultHandlingOptions>
    <Enabled>true</Enabled>
    <AutoRetryDelay>00:00:07</AutoRetryDelay>
  </TransientFaultHandlingOptions>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

WinForms 앱에서 IConfiguration 형식을 사용하려면 Microsoft.Extensions.Configuration.Xml NuGet 패키지에 대한 참조를 추가합니다. ConfigurationBuilder를 인스턴스화하고 AddXmlFileBuild()에 대한 호출을 연결합니다. 자세한 내용은 .NET Docs 이슈 #29679를 참조하세요.

.NET 5 이하 버전에서는 동일한 요소 이름을 사용하는 반복 요소를 구분하는 name 특성을 추가합니다. .NET 6 이상 버전에서 XML 구성 공급자는 반복 요소를 자동으로 인덱싱합니다. 즉, 키에 "0" 인덱스를 사용하고 요소가 하나만 있는 경우를 제외하고는 name 특성을 지정할 필요가 없습니다. (.NET 6 이상으로 업그레이드하는 경우 이 동작 변경으로 인해 중단이 발생할 수 있습니다. 자세한 내용은 반복 XML 요소에 인덱스 포함을 참조하세요.)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

다음 코드는 이전 구성 파일을 읽고 키 및 값을 표시합니다.

IConfigurationRoot configurationRoot = builder.Configuration;

string key00 = "section:section0:key:key0";
string key01 = "section:section0:key:key1";
string key10 = "section:section1:key:key0";
string key11 = "section:section1:key:key1";

string? val00 = configurationRoot[key00];
string? val01 = configurationRoot[key01];
string? val10 = configurationRoot[key10];
string? val11 = configurationRoot[key11];

Console.WriteLine($"{key00} = {val00}");
Console.WriteLine($"{key01} = {val01}");
Console.WriteLine($"{key10} = {val10}");
Console.WriteLine($"{key10} = {val11}");

애플리케이션은 다음 샘플 출력을 작성합니다.

// Sample output:
//    section:section0:key:key0 = value 00
//    section:section0:key:key1 = value 01
//    section:section1:key:key0 = value 10
//    section:section1:key:key0 = value 11

특성을 사용하여 값을 제공할 수 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

이전 구성 파일은 value와 함께 다음 키를 로드합니다.

  • key:attribute
  • section:key:attribute

INI 구성 공급자

IniConfigurationProvider 클래스는 런타임에 있는 INI 파일에서 구성을 로드합니다. Microsoft.Extensions.Configuration.Ini NuGet 패키지를 설치합니다.

다음 코드는 모든 구성 공급자를 지우고 두 개의 INI 파일을 소스로 사용하여 IniConfigurationProvider를 추가합니다.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Configuration.Sources.Clear();

IHostEnvironment env = builder.Environment;

builder.Configuration
    .AddIniFile("appsettings.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"appsettings.{env.EnvironmentName}.ini", true, true);

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

다양한 구성 설정을 사용하는 예제 appsettings.ini 파일은 다음과 같습니다.

SecretKey="Secret key value"

[TransientFaultHandlingOptions]
Enabled=True
AutoRetryDelay="00:00:07"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

다음 코드는 이전 구성 설정을 콘솔 창에 기록하여 표시합니다.

foreach ((string key, string? value) in
    builder.Configuration.AsEnumerable().Where(t => t.Value is not null))
{
    Console.WriteLine($"{key}={value}");
}

애플리케이션은 다음 샘플 출력을 작성합니다.

// Sample output:
//    TransientFaultHandlingOptions:Enabled=True
//    TransientFaultHandlingOptions:AutoRetryDelay=00:00:07
//    SecretKey=Secret key value
//    Logging:LogLevel:Microsoft=Warning
//    Logging:LogLevel:Default=Information

환경 변수 구성 공급자

기본 구성을 사용하여 EnvironmentVariablesConfigurationProviderappsettings.json, appsettings.Environment.json, 비밀 관리자를 읽은 후 환경 변수 키-값 쌍에서 구성을 로드합니다. 따라서 환경에서 읽은 키 값이 appsettings.json, appsettings.Environment.json 및 비밀 관리자에서 읽은 값을 재정의합니다.

: 구분 기호는 모든 플랫폼의 환경 변수 계층적 키에서 작동하지 않습니다. 예를 들어 : 구분 기호는 Bash에서 지원되지 않습니다. 모든 플랫폼에서 지원되는 이중 밑줄(__)은 환경 변수의 모든 : 구분 기호를 자동으로 바꿉니다.

TransientFaultHandlingOptions 클래스를 살펴보겠습니다.

public class TransientFaultHandlingOptions
{
    public bool Enabled { get; set; }
    public TimeSpan AutoRetryDelay { get; set; }
}

다음 set 명령은 SecretKeyTransientFaultHandlingOptions의 환경 키와 값을 설정합니다.

set SecretKey="Secret key from environment"
set TransientFaultHandlingOptions__Enabled="true"
set TransientFaultHandlingOptions__AutoRetryDelay="00:00:13"

이러한 환경 설정은 설정된 명령 창에서 시작된 프로세스에서만 설정됩니다. Visual Studio에서 시작된 웹앱에서는 읽지 않습니다.

Visual Studio 2019 이상에서는 시작 프로필 대화 상자를 사용하여 환경 변수를 지정할 수 있습니다.

Launch Profiles dialog showing environment variables

다음 setx 명령을 사용하여 Windows에서 환경 키 및 값을 설정할 수 있습니다. set와 달리, setx 설정은 유지됩니다. /M은 시스템 환경에서 변수를 설정합니다. /M 스위치를 사용하지 않으면 사용자 환경 변수가 설정됩니다.

setx SecretKey "Secret key from setx environment" /M
setx TransientFaultHandlingOptions__Enabled "true" /M
setx TransientFaultHandlingOptions__AutoRetryDelay "00:00:05" /M

이전 명령이 apsettings.jsonappsettings.Environment.json 설정을 재정의하는지 테스트하려면:

  • Visual Studio 사용: Visual Studio를 종료하고 다시 시작합니다.
  • CLI 사용: 새 명령 창을 시작하고 dotnet run을 입력합니다.

접두사

환경 변수에 대한 접두사를 지정하려면 문자열을 사용하여 AddEnvironmentVariables를 호출합니다.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.AddEnvironmentVariables(prefix: "CustomPrefix_");

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

위의 코드에서

  • config.AddEnvironmentVariables(prefix: "CustomPrefix_")는 기본 구성 공급자 뒤에 추가됩니다. 구성 공급자 순서 지정 예제는 XML 구성 공급자를 참조하세요.
  • CustomPrefix_ 접두사를 사용하여 설정된 환경 변수는 기본 구성 공급자를 재정의합니다. 여기에는 접두사 없는 환경 변수가 포함됩니다.

구성 키-값 쌍을 읽으면 접두사는 제거됩니다.

기본 구성은 DOTNET_ 접두사가 붙은 환경 변수 및 명령줄 인수를 로드합니다. DOTNET_ 접두사는 .NET에서 호스트앱 구성에 사용되지만 사용자 구성에는 사용되지 않습니다.

호스트 및 앱 구성에 대한 자세한 내용은 .NET 제네릭 호스트를 참조하세요.

연결 문자열 접두사

구성 API에는 네 개의 연결 문자열 환경 변수에 대한 특별한 처리 규칙이 있습니다. 해당 연결 문자열은 앱 환경의 Azure 연결 문자열을 구성하는 데 관련됩니다. 기본 구성을 사용하거나 AddEnvironmentVariables에 제공된 접두사가 없는 경우 표에 표시된 접두사가 붙은 환경 변수가 앱에 로드됩니다.

연결 문자열 접두사 공급자
CUSTOMCONNSTR_ 사용자 지정 공급자
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

표에 표시된 네 개 접두사 중 하나가 붙은 환경 변수가 검색되어 구성으로 로드되면 다음과 같이 됩니다.

  • 환경 변수 접두사를 제거하고 구성 키 섹션(ConnectionStrings)을 추가하여 구성 키가 생성됩니다.
  • 데이터베이스 연결 제공자(지정된 공급자가 없는 CUSTOMCONNSTR_ 제외)를 나타내는 새 구성 키-값 쌍이 생성됩니다.
환경 변수 키 변환된 구성 키 공급자 구성 항목
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 구성 항목이 생성되지 않습니다.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} 키: ConnectionStrings:{KEY}_ProviderName:
값: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} 키: ConnectionStrings:{KEY}_ProviderName:
값: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} 키: ConnectionStrings:{KEY}_ProviderName:
값: System.Data.SqlClient

launchSettings.json에 설정된 환경 변수

launchSettings.json에 설정된 환경 변수는 시스템 환경에 설정된 변수를 재정의합니다.

Azure App Service 설정

Azure App Service설정>구성 페이지에서 새 애플리케이션 설정을 선택합니다. Azure App Service 애플리케이션 설정은,

  • 미사용 시 암호화되고 암호화된 채널을 통해 전송됩니다.
  • 환경 변수로 노출됩니다.

명령줄 구성 공급자

기본 구성을 사용하여 CommandLineConfigurationProvider는 다음 구성 소스 뒤에 명령줄 인수 키-값 쌍에서 구성을 로드합니다.

  • appsettings.jsonappsettings.Environment.json 파일
  • Development 발 환경의 앱 비밀(비밀 관리자)
  • 환경 변수입니다.

기본적으로 명령줄에 설정된 구성 값은 다른 모든 구성 공급자를 사용하여 설정된 구성 값을 재정의합니다.

Visual Studio 2019 이상에서는 시작 프로필 대화 상자를 사용하여 명령줄 인수를 지정할 수 있습니다.

Launch Profiles dialog showing command-line arguments

명령줄 인수

다음 명령은 =를 사용하여 키 및 값을 설정합니다.

dotnet run SecretKey="Secret key from command line"

다음 명령은 /를 사용하여 키 및 값을 설정합니다.

dotnet run /SecretKey "Secret key set from forward slash"

다음 명령은 --를 사용하여 키 및 값을 설정합니다.

dotnet run --SecretKey "Secret key set from double hyphen"

키 값은,

  • = 다음에 와야 합니다. 또는 값이 공백에 다음에 오는 경우 키에 -- 또는 / 접두사가 있어야 합니다.
  • =이 사용된 경우 필요하지 않습니다. 예: SomeKey=.

같은 명령 내에서 =을 사용하는 명령줄 인수 키-값 쌍을 공백을 사용하는 키-값 쌍과 함께 사용하지 마세요.

파일별 키 구성 공급자

KeyPerFileConfigurationProvider는 디렉터리의 파일을 구성 키-값 쌍으로 사용합니다. 키는 파일 이름이고, 값은 파일의 콘텐츠입니다. 파일별 키 구성 공급자는 Docker 호스팅 시나리오에서 사용됩니다.

파일별 키 구성을 활성화하려면 ConfigurationBuilder 인스턴스에서 AddKeyPerFile 확장 메서드를 호출합니다. 파일의 directoryPath는 절대 경로여야 합니다.

오버로드에서는 다음을 지정할 수 있습니다.

  • 소스를 구성하는 Action<KeyPerFileConfigurationSource> 대리자
  • 디렉터리가 선택 사항인지 여부와 디렉터리의 경로

두 개의 밑줄(__)은 파일 이름에서 구성 키 구분 기호로 사용됩니다. 예를 들어, 파일 이름 Logging__LogLevel__System은 구성 키 Logging:LogLevel:System을 생성합니다.

호스트를 빌드할 때 ConfigureAppConfiguration을 호출하여 앱의 구성을 지정합니다.

.ConfigureAppConfiguration((_, configuration) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");

    configuration.AddKeyPerFile(directoryPath: path, optional: true);
})

메모리 구성 공급자

MemoryConfigurationProvider는 메모리 내 컬렉션을 구성 키-값 쌍으로 사용합니다.

다음 코드는 구성 시스템에 메모리 컬렉션을 추가합니다.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.AddInMemoryCollection(
    new Dictionary<string, string?>
    {
        ["SecretKey"] = "Dictionary MyKey Value",
        ["TransientFaultHandlingOptions:Enabled"] = bool.TrueString,
        ["TransientFaultHandlingOptions:AutoRetryDelay"] = "00:00:07",
        ["Logging:LogLevel:Default"] = "Warning"
    });

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

이전 코드에서 MemoryConfigurationBuilderExtensions.AddInMemoryCollection(IConfigurationBuilder, IEnumerable<KeyValuePair<String,String>>)은 기본 구성 공급자 뒤에 메모리 공급자를 추가합니다. 구성 공급자 순서 지정 예제는 XML 구성 공급자를 참조하세요.

참고 항목