.NET의 구성

.NET의 구성은 하나 이상의 구성 공급자를 사용하여 수행합니다. 구성 공급자는 다양한 구성 원본을 사용하여 키-값 쌍에서 구성 데이터를 읽습니다.

  • 설정 파일(예: appsettings.json)
  • 환경 변수
  • Azure Key Vault
  • Azure App Configuration
  • 명령줄 인수
  • 설치되거나 만들어진 사용자 지정 공급자
  • 디렉터리 파일
  • 메모리 내 .NET 개체
  • 타사 공급자

참고 항목

.NET 런타임 자체 구성에 대한 자세한 내용은 .NET 런타임 구성 설정을 참조하세요.

개념과 추상화

하나 이상의 구성 원본이 주어지면 IConfiguration 형식은 구성 데이터의 통합 보기를 제공합니다. 구성은 읽기 전용이며 구성 패턴은 프로그래밍 방식으로 쓸 수 있도록 설계되지 않았습니다. IConfiguration 인터페이스는 다음 다이어그램에 표시된 것처럼 모든 구성 원본의 단일 표현입니다.

The `IConfiguration` interface is a single representation of all the configuration sources.

콘솔 앱 구성

기본적으로 dotnet new 명령 템플릿이나 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[]) 메서드는 우선 순위가 가장 높은 것부터 가장 낮은 것 순으로 앱에 대한 기본 구성을 제공합니다.

  1. 명령줄 구성 공급자를 사용하는 명령줄 인수
  2. 환경 변수 구성 공급자를 사용하는 환경 변수
  3. 앱이 Development 환경에서 실행되는 경우 앱 비밀
  4. JSON 구성 공급자를 사용하는 appsettings.json
  5. JSON 구성 공급자를 사용하는 appsettings.Environment.json. 예: appsettings.Production.jsonappsettings.Development.json.
  6. ChainedConfigurationProvider: 기존 IConfiguration을 소스로 추가합니다.

구성 공급자를 추가하면 이전 구성 값이 재정의됩니다. 예를 들어, 명령줄 구성 공급자는 마지막에 추가되므로 다른 공급자의 모든 값을 재정의합니다. SomeKeyappsettings.json과 환경 모두에 설정된 경우 환경 값은 appsettings.json 뒤에 추가되었으므로 사용됩니다.

바인딩

.NET 구성 추상화를 사용하는 주요 이점 중 하나는 구성 값을 .NET 개체 인스턴스에 바인딩하는 기능입니다. 예를 들어, JSON 구성 공급자는 appsettings.json 파일을 .NET 개체에 매핑하는 데 사용될 수 있으며 종속성 주입과 함께 사용됩니다. 이를 통해 옵션 패턴을 사용할 수 있습니다. 옵션 패턴은 클래스를 사용하여 관련 설정 그룹에 대한 강력한 형식의 액세스를 제공합니다. .NET 구성은 다양한 추상화를 제공합니다. 다음 인터페이스를 생각해 볼 수 있습니다.

이러한 추상화는 기본 구성 공급자(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

기본 예제

제네릭 호스트 방식의 도움 없이 기본 형식으로 구성 값에 액세스하려면 ConfigurationBuilder 형식을 직접 사용합니다.

System.Configuration.ConfigurationBuilder 형식은 Microsoft.Extensions.Configuration.ConfigurationBuilder 형식과 다릅니다. 이 내용은 모두 Microsoft.Extensions.* NuGet 패키지 및 네임스페이스에만 해당됩니다.

다음 C# 프로젝트를 생각해 볼 수 있습니다.

<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="8.0.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
  </ItemGroup>

</Project>

위의 프로젝트 파일은 여러 구성 NuGet 패키지를 참조합니다.

예제 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" 파일을 추가합니다.
  • 환경 변수 구성 공급자가 인식하는 환경 변수를 추가합니다.
  • config 인스턴스를 사용하여 필수 "Settings" 섹션과 해당 Settings 인스턴스를 가져옵니다.

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>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.Hosting" Version="8.0.0" />
  </ItemGroup>

</Project>

앞의 프로젝트 파일은 다음을 정의합니다.

  • 애플리케이션은 실행 파일입니다.
  • 프로젝트를 컴파일할 때 appsettings.json 파일이 출력 디렉터리에 복사됨
  • Microsoft.Extensions.Hosting NuGet 패키지 참조가 추가되었습니다.

다음 내용이 포함된 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의 구성 공급자를 참조하세요.

참고 항목