ASP.NET Core의 구성

작성자: Rick AndersonKirk Larkin

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

ASP.NET Core에서 애플리케이션 구성은 하나 이상의 구성 공급자를 사용하여 수행합니다. 구성 공급자는 다음과 같은 다양한 구성 소스를 사용하여 키-값 쌍에서 구성 데이터를 읽습니다.

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

이 문서에서는 ASP.NET Core의 구성에 대한 정보를 제공합니다. 콘솔 앱에서 구성을 사용하는 방법에 대한 자세한 내용은 .NET 구성을 참조하세요.

애플리케이션 및 호스트 구성

ASP.NET Core 앱은 호스트를 구성 및 실행합니다. 호스트는 앱 시작 및 수명 관리를 담당합니다. ASP.NET Core 템플릿은 호스트를 포함하는 WebApplicationBuilder을(를) 만듭니다. 일부 구성은 호스트와 애플리케이션 구성 공급자 모두에서 수행할 수 있지만 일반적으로 호스트에 필요한 구성만 호스트 구성에서 수행해야 합니다.

애플리케이션 구성은 우선 순위가 가장 높으며 다음 섹션에 자세히 설명되어 있습니다. 호스트 구성은 애플리케이션 구성을 따르며 이 문서에 설명되어 있습니다.

기본 애플리케이션 구성 원본

dotnet new 또는 Visual Studio를 사용하여 만든 ASP.NET Core 웹앱은 다음 코드를 생성합니다.

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder는 미리 구성된 기본값을 사용하여 WebApplicationBuilder 클래스의 새 인스턴스를 초기화합니다. 초기화된 WebApplicationBuilder(builder)은(는) 가장 높은 우선 순위부터 가장 낮은 우선 순위까지 다음 순서로 앱의 기본 구성을 제공합니다.

  1. 명령줄 구성 공급자를 사용하는 명령줄 인수
  2. 접두사 없는 환경 변수 구성 공급자를 사용하는 접두사 없는 환경 변수.
  3. 사용자 비밀 - 앱이 Development 환경에서 실행되는 경우.
  4. JSON 구성 공급자를 사용하는 appsettings.{Environment}.json. 예를 들어 appsettings.Production.jsonappsettings.Development.json를 지정합니다.
  5. JSON 구성 공급자를 사용하는appsettings.json.
  6. 다음 섹션에 설명된 호스트 구성에 대한 대체입니다.

기본 호스트 구성 원본

다음 목록에는 가장 높은 우선 순위에서 WebApplicationBuilder에 대한 가장 낮은 우선 순위까지의 기본 호스트 구성 원본이 포함되어 있습니다.

  1. 명령줄 구성 공급자를 사용하는 명령줄 인수
  2. 환경 변수 구성 공급자를 사용하는 DOTNET_ 접두사가 붙은 환경 변수.
  3. 환경 변수 구성 공급자를 사용하는 ASPNETCORE_ 접두사가 붙은 환경 변수.

.NET 제네릭 호스트웹 호스트의 경우, 기본 호스트 구성 원본을 가장 높은 우선 순위에서 가장 낮은 우선 순위로 지정합니다.

  1. 환경 변수 구성 공급자를 사용하는 ASPNETCORE_ 접두사가 붙은 환경 변수.
  2. 명령줄 구성 공급자를 사용하는 명령줄 인수
  3. 환경 변수 구성 공급자를 사용하는 DOTNET_ 접두사가 붙은 환경 변수.

구성 값이 호스트 및 애플리케이션 구성에서 설정되면 애플리케이션 구성이 사용됩니다.

호스트 변수

다음 변수는 호스트 작성기를 초기화할 떄 조기에 잠기므로 애플리케이션 구성의 영향을 받을 수 없습니다.

다른 모든 호스트 설정은 호스트 구성 대신 애플리케이션 구성에서 읽습니다.

URLS은(는) 부트스트랩 설정이 아닌 많은 일반적인 호스트 설정 중 하나입니다. 이전 목록에 없는 다른 모든 호스트 설정과 마찬가지로 URLS은(는) 나중에 애플리케이션 구성에서 읽습니다. 호스트 구성은 애플리케이션 구성에 대한 대체이므로 호스트 구성을 사용하여 URLS을(를) 설정할 수 있지만 애플리케이션 구성의 구성 원본(예: appsettings.json)에 의해 재정의됩니다.

자세한 내용은 콘텐츠 루트, 앱 이름 및 환경 변경환경 변수 또는 명령줄별 콘텐츠 루트, 앱 이름 및 환경 변경을 참조하세요.

이 문서의 나머지 섹션은 애플리케이션 구성을 참조합니다.

애플리케이션 구성 공급자

다음 코드는 추가된 순서대로 사용하도록 설정된 구성 공급자를 표시합니다.

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

우선 순위가 가장 높은 기본 구성 원본의 이전 목록은 공급자가 템플릿 생성 애플리케이션에 추가되는 순서와 반대 순서로 공급자를 표시합니다. 예를 들어 JSON 구성 공급자명령줄 구성 공급자 앞에 추가됩니다.

나중에 추가되는 구성 공급자는 가장 높은 우선 순위를 가지므로 이전 키 설정을 재정의합니다. 예를 들어 MyKeyappsettings.json과 환경 모두에서 설정된 경우 환경 값이 사용됩니다. 명령줄 구성 공급자는 기본 구성 공급자를 사용하여 다른 모든 공급자를 재정의합니다.

CreateBuilder에 대한 자세한 내용은 기본 작성기 설정을 참조하세요.

appsettings.json

다음 appsettings.json 파일을 살펴보세요.

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

기본 JsonConfigurationProvider는 다음과 같은 순서로 구성을 로드합니다.

  1. appsettings.json
  2. appsettings.{Environment}.json : 예를 들어 appsettings.Production.jsonappsettings.Development.json 파일입니다. 파일 IHostingEnvironment.EnvironmentName의 환경 버전은 . 자세한 내용은 ASP.NET Core에서 여러 환경 사용을 참조하세요.

appsettings.{Environment}.json 값은 appsettings.json의 키를 재정의합니다. 예를 들어 기본적으로 다음과 같습니다.

  • 개발 환경에서는 appsettings.Development.json 구성이 appsettings.json에서 찾은 값을 덮어씁니다.
  • 프로덕션 환경에서는 appsettings.Production.json 구성이 appsettings.json에서 찾은 값을 덮어씁니다. Azure에 앱을 배포하는 경우를 예로 들 수 있습니다.

구성 값을 보장해야 하는 경우 GetValue를 참조 하십시오. 위의 예제에서는 문자열만 읽고 기본값을 지원하지 않습니다.

기본 구성을 사용하여 appsettings.jsonappsettings.{Environment}.json 파일은 reloadOnChange: true를 통해 사용하도록 설정됩니다. 앱이 시작된 appsettings.jsonappsettings.{Environment}.json 파일에 대한 변경 내용은 JSON 구성 공급자에서 읽습니다.

appsettings.json의 주석

appsettings.json JavaScript 또는 C# 스타일 주석을 사용하여 주석 및 appsettings.{Environment}.json 파일에서 지원됩니다.

옵션 패턴을 사용하여 계층적 구성 데이터 바인딩

관련 구성 값을 읽는 기본 방법은 옵션 패턴를 사용하는 것입니다. 예를 들어 다음 구성 값을 읽으려면:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

다음 PositionOptions 클래스를 만듭니다.

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

옵션 클래스:

  • 매개 변수가 없는 public 생성자를 사용하는 비추상이어야 합니다.
  • 형식의 모든 공용 읽기-쓰기 속성이 바인딩됩니다.
  • 필드가 바인딩되지 않습니다. 위 코드에서 Position은 바운딩되지 않습니다. Position 필드를 사용하므로 클래스를 구성 공급자에 바인딩할 때 문자열 "Position"을 앱에서 하드 코딩하지 않아도 됩니다.

코드는 다음과 같습니다.

  • ConfigurationBinder.Bind를 호출하여 PositionOptions 클래스를 Position 섹션에 바인딩합니다.
  • Position 구성 데이터를 표시합니다.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

위 코드에서는 기본적으로 앱을 시작한 후의 JSON 구성 파일의 변경 사항을 읽습니다.

ConfigurationBinder.Get<T>는 지정된 형식을 바인딩하고 반환합니다. ConfigurationBinder.Get<T>ConfigurationBinder.Bind를 사용하는 것보다 편리할 수 있습니다. 다음 코드에서는 ConfigurationBinder.Get<T>PositionOptions 클래스를 함께 사용하는 방법을 보여 줍니다.

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

위 코드에서는 기본적으로 앱을 시작한 후의 JSON 구성 파일의 변경 사항을 읽습니다.

옵션 패턴을 사용하는 경우 한 가지 대체 방법은 Position 섹션을 바인딩하고 종속성 주입 서비스 컨테이너에 추가하는 것입니다. 다음 코드에서 PositionOptionsConfigure를 통해 서비스 컨테이너에 추가되고 구성에 바인딩됩니다.

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

위의 코드를 사용하여 다음 코드는 위치 옵션을 읽습니다.

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

위 코드에서는 앱을 시작한 후의 JSON 구성 파일의 변경 사항은 읽지 않습니다. 앱을 시작한 후의 변경 사항을 읽으려면 IOptionsSnapshot을 사용합니다.

기본 구성을 사용하여 appsettings.jsonappsettings.{Environment}.json 파일은 reloadOnChange: true를 통해 사용하도록 설정됩니다. 앱이 시작된 appsettings.jsonappsettings.{Environment}.json 파일에 대한 변경 내용은 JSON 구성 공급자에서 읽습니다.

추가 JSON 구성 파일 추가에 대한 자세한 내용은 이 문서의 JSON 구성 공급자를 참조하세요.

서비스 컬렉션 결합

서비스를 등록하고 옵션을 구성하는 다음 메서드를 고려합니다.

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

관련 등록 그룹을 확장 메서드로 이동하여 서비스를 등록할 수 있습니다. 예를 들어, 구성 서비스는 다음 클래스에 추가됩니다.

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

나머지 서비스는 유사한 클래스에 등록됩니다. 다음 코드는 새 확장 메서드를 사용하여 서비스를 등록합니다.

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

참고:services.Add{GROUP_NAME} 확장 메서드는 서비스를 추가하고 잠재적으로 구성합니다. 예를 들어 AddControllersWithViews는 보기에 필요한 서비스 MVC 컨트롤러를 추가하고 AddRazorPages는 Razor Pages에 필요한 서비스를 추가합니다.

보안 및 사용자 비밀

구성 데이터 지침:

  • 구성 공급자 코드 또는 일반 텍스트 구성 파일에 암호 또는 기타 중요한 데이터를 절대 저장하지 마세요. 비밀 관리자 도구를 사용하여 개발에 사용되는 비밀을 저장할 수 있습니다.
  • 개발 또는 테스트 환경에서 프로덕션 비밀을 사용하지 마세요.
  • 의도치 않게 소스 코드 리포지토리에 커밋되는 일이 없도록 프로젝트 외부에서 비밀을 지정하세요.

기본적으로, 사용자 비밀 구성 원본은 JSON 구성 원본 뒤에 등록됩니다. 따라서 사용자 비밀 키가 appsettings.jsonappsettings.{Environment}.json의 키보다 우선합니다.

암호 또는 기타 중요한 데이터 저장에 대한 자세한 정보:

Azure Key Vault가 ASP.NET Core 앱에 대한 앱 비밀을 안전하게 저장합니다. 자세한 내용은 ASP.NET Core의 Azure Key Vault 구성 공급자를 참조하세요.

접두사가 없는 환경 변수

접두사가 없는 환경 변수는 ASPNETCORE_ 또는 DOTNET_ 접두사가 붙은 변수가 아니라 환경 변수입니다. 예를 들어, ASP.NET Core 웹 애플리케이션 템플릿은 launchSettings.json에서 "ASPNETCORE_ENVIRONMENT": "Development"을 설정합니다. ASPNETCORE_DOTNET_ 환경 변수에 대한 자세한 내용은 다음을 참조하세요.

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

: 구분 기호는 모든 플랫폼의 환경 변수 계층적 키에서 작동하지 않습니다. 이중 밑줄 __은 다음과 같습니다.

  • 모든 플랫폼에서 지원됩니다. 예를 들어 : 구분 기호는 Bash에서 지원되지 않지만 __은 지원됩니다.
  • 자동으로 :으로 대체

다음 set 명령은,

  • Windows에서 위의 예제에 나오는 환경 키 및 값을 설정합니다.
  • 샘플 다운로드를 사용하는 경우 설정을 테스트합니다. dotnet run 명령은 프로젝트 디렉터리에서 실행해야 합니다.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

위의 환경 설정은,

  • 설정된 명령 창에서 시작된 프로세스에서만 설정됩니다.
  • Visual Studio에서 시작된 브라우저에서는 읽을 수 없습니다.

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

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

위의 명령이 appsettings.jsonappsettings.{Environment}.json을 재정의하는지 테스트하려면:

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

환경 변수의 접두사를 지정하는 문자열을 사용하여 AddEnvironmentVariables를 호출합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

var app = builder.Build();

위의 코드에서

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

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

다음 명령은 사용자 지정 접두사를 테스트합니다.

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

기본 구성DOTNET_ASPNETCORE_ 접두사가 붙은 환경 변수 및 명령줄 인수를 로드합니다. DOTNET_ASPNETCORE_ 접두사는 ASP.NET Core에서 호스트 및 앱 구성에 사용되지만, 사용자 구성에는 사용되지 않습니다. 호스트 및 앱 구성에 대한 자세한 내용은 .NET 제네릭 호스트를 참조하세요.

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

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

자세한 내용은 Azure 앱: Azure Portal을 사용하여 앱 구성 재정의를 참조하세요.

Azure 데이터베이스 연결 문자열에 대한 자세한 내용은 연결 문자열 접두사를 참조하세요.

환경 변수 명명

환경 변수의 이름은 appsettings.json 파일의 구조를 반영합니다. 계층 구조의 각 요소는 이중 밑줄(권장) 또는 콜론으로 구분됩니다. 요소 구조에 배열이 포함된 경우, 해당 배열 인덱스는 이 경로의 추가 요소 이름으로 처리되어야 합니다. 다음 appsettings.json 파일 및 환경 변수라고 표시된 해당 값을 살펴보세요.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

환경 변수

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

생성된 launchSettings.json에 설정된 환경 변수

설정된 launchSettings.json 환경 변수는 시스템 환경에서 설정된 변수를 재정의합니다. 예를 들어 ASP.NET Core 웹 템플릿은 엔드포인트 구성을 다음으로 launchSettings.json 설정하는 파일을 생성합니다.

"applicationUrl": "https://localhost:5001;http://localhost:5000"

applicationUrl 구성은 ASPNETCORE_URLS 환경 변수를 설정하고 환경에 설정된 값을 재정의합니다.

Linux에서 환경 변수 이스케이프

Linux에서는 URL 환경 변수의 값을 이스케이프 처리하여 systemd가 구문 분석을 할 수 있도록 해야 합니다. http:--localhost:5001을 생성하는 Linux 도구 systemd-escape를 사용하세요.

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

환경 변수 표시

다음 코드는 애플리케이션 시작 시 환경 설정을 디버그할 때 도움이 될 수 있는 환경 변수 및 값을 표시합니다.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

명령줄

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

  • appsettings.jsonappsettings.{Environment}.json 파일입니다.
  • 개발 환경의 앱 비밀.
  • 환경 변수입니다.

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

명령줄 인수

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

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

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

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

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

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

키 값은,

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

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

스위치 매핑

스위치 매핑은 이름 교체 논리를 지원합니다. AddCommandLine 메서드에 스위치 교체 사전을 제공합니다.

스위치 매핑 사전을 사용하면 명령줄 인수를 통해 제공된 키와 일치하는 키에 대해 사전을 검사합니다. 사전에서 명령줄 키가 발견되면 사전 값이 다시 전달되어 앱 구성의 키-값 쌍이 설정됩니다. 단일 대시(-) 접두사가 붙은 명령줄 키에는 스위치 매핑이 필수입니다.

스위치 매핑 사전 키 규칙:

  • 스위치는 - 또는 --으로 시작해야 합니다.
  • 스위치 매핑 사전이 중복 키를 포함하면 안 됩니다.

스위치 매핑 사전을 사용하려면 AddCommandLine에 대한 호출에 전달합니다.


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

다음 명령을 실행하여 키 교체를 테스트합니다.

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

다음 코드는 교체된 키의 키 값을 보여 줍니다.

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

스위치 매핑을 사용하는 앱의 경우 CreateDefaultBuilder에 대한 호출은 인수를 전달하지 않아야 합니다. CreateDefaultBuilder 메서드의 AddCommandLine 호출에는 매핑된 스위치가 포함되지 않으며 CreateDefaultBuilder에 스위치 매핑 사전을 전달할 방법은 없습니다. 해결 방법으로 CreateDefaultBuilder에 인수를 전달하지 않고 대신 ConfigurationBuilder 메서드의 AddCommandLine 메서드에서 인수와 스위치 매핑 사전을 모두 처리하도록 할 수 있습니다.

Visual Studio에서 환경 및 명령줄 인수 설정

Visual Studio의 시작 프로필 대화 상자에서 환경 및 명령줄 인수를 설정할 수 있습니다.

  • 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.
  • 디버그 > 일반 탭을 선택하고 디버그 시작 프로필 UI 열기를 선택합니다.

계층적 구성 데이터

구성 API는 구성 키에 구분 기호를 사용해 계층적 데이터를 평면화하여 계층적 구성 데이터를 읽습니다.

샘플 다운로드에는 다음 appsettings.json 파일이 포함되어 있습니다.

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

샘플 다운로드의 다음 코드는 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

계층적 구성 데이터를 읽는 기본 방법은 옵션 패턴을 사용하는 것입니다. 자세한 내용은 이 문서의 계층적 구성 데이터 바인딩을 참조하세요.

구성 데이터에서는 GetSectionGetChildren 메서드를 사용하여 섹션과 섹션의 자식을 격리할 수 있습니다. 이러한 메서드에 대해서는 나중에 GetSection, GetChildren 및 Exists에서 설명합니다.

구성 키 및 값

구성 키는,

  • 대/소문자를 구분하지 않습니다. 예를 들어 ConnectionStringconnectionstring은 동일한 키로 처리됩니다.
  • 둘 이상의 구성 공급자에서 키와 값이 설정된 경우 추가된 마지막 공급자의 값이 사용됩니다. 자세한 내용은 기본 구성을 참조하세요.
  • 계층적 키
    • 구성 API 내에서는 콜론 구분 기호(:)가 모든 플랫폼에 적용됩니다.
    • 환경 변수에서는 콜론 구분 기호가 일부 플랫폼에 적용되지 않을 수 있습니다. 두 개의 밑줄(__)은 모든 플랫폼에서 지원되며 콜론(:)으로 자동 변환됩니다.
    • Azure Key Vault에서 계층적 키는 --를 구분 기호로 사용합니다. Azure Key Vault 구성 공급자는 암호를 앱의 구성으로 로드할 때 --를 자동으로 :으로 바꿉니다.
  • ConfigurationBinder는 구성 키에 배열 인덱스를 사용하여 배열을 개체에 바인딩하는 것을 지원합니다. 배열 바인딩에 대해서는 클래스에 배열 바인딩 섹션에서 설명합니다.

구성 값은,

  • 문자열입니다.
  • Null 값은 구성에 저장하거나 개체에 바인딩할 수 없습니다.

구성 공급자

다음 표에서는 ASP.NET Core 앱에서 사용할 수 있는 구성 공급자를 보여 줍니다.

공급자 다음에서 구성 제공
Azure Key Vault 구성 공급자 Azure Key Vault
Azure 앱 구성 공급자 Azure App Configuration
명령줄 구성 공급자 명령줄 매개 변수
사용자 지정 구성 공급자 사용자 지정 소스
환경 변수 구성 공급자 환경 변수
파일 구성 공급자 INI, JSON 및 XML 파일
파일별 키 구성 공급자 디렉터리 파일
메모리 구성 공급자 메모리 내 컬렉션
사용자 비밀 사용자 프로필 디렉터리의 파일

구성 공급자에서 지정한 순서로 구성 소스를 읽습니다. 앱에 필요한 기본 구성 소스에 대한 우선 순위에 맞게 구성 공급자를 코드에 정렬하세요.

구성 공급자의 일반적인 순서는 다음과 같습니다.

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. 사용자 비밀
  4. 환경 변수 구성 공급자를 사용하는 환경 변수
  5. 명령줄 구성 공급자를 사용하는 명령줄 인수

일반적인 방식은 명령줄 구성 공급자를 일련의 공급자에서 마지막에 추가하는 것이므로, 다른 공급자에서 설정한 구성을 명령줄 인수로 재정의할 수 있습니다.

위의 공급자 시퀀스는 기본 구성에서 사용됩니다.

연결 문자열 접두사

구성 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

파일 구성 공급자

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

INI 구성 공급자

IniConfigurationProvider는 런타임에 INI 파일 키-값 쌍에서 구성을 로드합니다.

다음 코드는 여러 구성 공급자를 추가합니다.

var builder = WebApplication.CreateBuilder(args);

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

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

위의 코드에서 MyIniConfig.iniMyIniConfig.{Environment}.ini 파일의 설정은 다음의 설정에 의해 재정의됩니다.

샘플 다운로드에는 다음 MyIniConfig.ini 파일이 포함되어 있습니다.

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

JSON 구성 공급자

JsonConfigurationProvider은(는) JSON 파일 키-값 쌍에서 구성을 로드합니다.

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

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

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

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

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

일반적으로 사용자 지정 JSON 파일은 환경 변수 구성 공급자명령줄 구성 공급자에 설정된 값을 재정의하지 않습니다.

XML 구성 공급자

XmlConfigurationProvider는 런타임에 XML 파일 키-값 쌍에서 구성을 로드합니다.

다음 코드는 여러 구성 공급자를 추가합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

위의 코드에서 MyXMLFile.xmlMyXMLFile.{Environment}.xml 파일의 설정은 다음의 설정에 의해 재정의됩니다.

샘플 다운로드에는 다음 MyXMLFile.xml 파일이 포함되어 있습니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

같은 요소 이름을 사용하는 반복 요소는 다음과 같이 name 특성을 사용하여 요소를 구분하면 작동합니다.

<?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>

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

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

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

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

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

  • key:attribute
  • section:key:attribute

파일별 키 구성 공급자

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

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

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

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

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

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

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

메모리 구성 공급자

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

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

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

샘플 다운로드의 다음 코드는 위의 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

위의 코드에서 config.AddInMemoryCollection(Dict)기본 구성 공급자 뒤에 추가됩니다. 구성 공급자 순서 지정 예제는 JSON 구성 공급자를 참조하세요.

MemoryConfigurationProvider를 사용하는 또 다른 예제는 배열 바인딩을 참조하세요.

Kestrel 엔드포인트 구성

Kestrel 관련 엔드포인트 구성은 모든 서버 간 엔드포인트 구성을 재정의합니다. 서버 간 엔드포인트 구성에는 다음이 포함됩니다.

ASP.NET Core 웹 앱에서 사용되는 다음 appsettings.json 파일을 고려합니다.

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

위에 강조 표시된 마크업을 ASP.NET Core 웹앱에 사용하면서 다음과 같은 서버 간 엔드포인트 구성을 사용하여 명령줄에서 앱을 시작하는 경우,

dotnet run --urls="https://localhost:7777"

Kestrel은 https://localhost:7777이 아닌 appsettings.json 파일(https://localhost:9999)에서 Kestrel용으로 특별히 구성된 엔드포인트에 바인딩합니다.

환경 변수로 구성된 Kestrel 관련 엔드포인트를 고려합니다.

set Kestrel__Endpoints__Https__Url=https://localhost:8888

위 환경 변수에서 Https는 Kestrel 관련 엔드포인트의 이름입니다. 또한 위 appsettings.json 파일은 Https라는 Kestrel 관련 엔드포인트를 정의합니다. 기본적으로환경 변수 구성 공급자를 사용하는 환경 변수는 appsettings.{Environment}.json 이후에 읽혀지므로 위 환경 변수는 Https 엔드포인트에 사용됩니다.

GetValue

ConfigurationBinder.GetValue는 지정된 키를 사용하여 구성에서 단일 값을 추출하고 해당 값을 지정된 형식으로 변환합니다.

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

위의 코드에서 구성에 NumberKey가 없는 경우 기본값 99가 사용됩니다.

GetSection, GetChildren 및 Exists

이어지는 예제에서는 다음 MySubsection.json 파일을 고려하세요.

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

다음 코드는 구성 공급자에 추가 MySubsection.json 됩니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection 는 지정된 하위 섹션 키가 있는 구성 하위 섹션을 반환합니다.

다음 코드는 section1의 값을 반환합니다.

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

다음 코드는 section2:subsection0의 값을 반환합니다.

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSectionnull을 반환하지 않습니다. 일치하는 섹션을 찾을 수 없으면 빈 IConfigurationSection이 반환됩니다.

GetSection이 일치하는 섹션을 반환할 때 Value는 채워지지 않습니다. 섹션이 존재하면 KeyPath가 반환됩니다.

GetChildren 및 Exists

다음 코드는 다음에 대한 section2:subsection0값을 호출 IConfiguration.GetChildren 하고 반환합니다.

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

이전 코드는 섹션이 있는지 확인하기 위해 호출 ConfigurationExtensions.Exists 합니다.

배열 바인딩

ConfigurationBinder.Bind는 구성 키에 배열 인덱스를 사용하여 배열을 개체에 바인딩하는 것을 지원합니다. 숫자 키 세그먼트를 노출하는 모든 배열 형식은 POCO 클래스 배열에 배열을 바인딩할 수 있습니다.

샘플 다운로드고려합니다MyArray.json.

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

다음 코드는 구성 공급자에 추가 MyArray.json 됩니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

다음 코드는 구성을 읽고 값을 표시합니다.

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

위의 코드는 다음 출력을 반환합니다.

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

위의 출력에서 Index 3은 MyArray.json"4": "value40",에 해당하는 value40 값을 가집니다. 바인딩된 배열 인덱스는 연속되며 구성 키 인덱스에 바인딩되지 않습니다. 구성 바인더는 null 값을 바인딩하거나 바인딩된 개체에 null 항목을 만들 수 없습니다.

사용자 지정 구성 공급자

샘플 앱에서는 EF(Entity Framework)를 사용하여 데이터베이스에서 구성 키-값 쌍을 읽는 기본 구성 공급자를 만드는 방법을 보여 줍니다.

이 공급자의 특징은 다음과 같습니다.

  • 데모용으로 EF 메모리 내 데이터베이스를 사용합니다. 연결 문자열이 필요한 데이터베이스를 사용하려면 보조 ConfigurationBuilder를 구현하여 다른 구성 공급자에서 연결 문자열을 제공하세요.
  • 이 공급자는 시작 시 데이터베이스 테이블을 구성으로 읽어 들입니다. 이 공급자는 키별 기준으로 데이터베이스를 쿼리하지 않습니다.
  • 변경 시 다시 로드가 구현되지 않으므로 앱 시작 후 데이터베이스를 업데이트해도 앱 구성에 영향을 주지 않습니다.

데이터베이스에 구성 값을 저장하는 EFConfigurationValue 엔터티를 정의합니다.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

구성된 값을 저장 및 액세스하는 EFConfigurationContext를 추가합니다.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

IConfigurationSource를 구현하는 클래스를 만듭니다.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

ConfigurationProvider에서 상속하여 사용자 지정 구성 공급자를 만듭니다. 구성 공급자는 비어 있는 데이터베이스를 초기화합니다. 구성 키는 대/소문자를 구분하지 않으므로 데이터베이스를 초기화하는 데 사용되는 사전은 대/소문자를 구분하지 않는 비교자(StringComparer.OrdinalIgnoreCase)를 사용하여 생성됩니다.

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

AddEFConfiguration 확장 메서드를 사용하여 구성 소스를 ConfigurationBuilder에 추가할 수 있습니다.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

다음 코드는 다음에서 사용자 지정 EFConfigurationProvider 을 사용하는 방법을 보여줍니다.Program.cs

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

DI(종속성 주입)를 통해 구성에 액세스

IConfiguration 서비스를 확인하여 DI(종속성 주입)를 사용하여 구성을 서비스에 주입할 수 있습니다.

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

IConfiguration을 사용하여 값에 액세스하는 방법에 대한 내용은 이 문서의 GetValueGetSection, GetChildren 및 Exists를 참조하세요.

Razor Pages의 구성 액세스

다음 코드는 Razor 페이지의 구성 데이터를 표시합니다.

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

다음 코드에서 MyOptionsConfigure를 통해 서비스 컨테이너에 추가되고 구성에 바인딩됩니다.

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

다음 태그는 지시문을 @injectRazor 사용하여 옵션 값을 확인하고 표시합니다.

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

MVC 뷰 파일의 구성 액세스

다음 코드는 MVC 뷰의 구성 데이터를 표시합니다.

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Program.cs의 구성 액세스

다음 코드는 Program.cs 파일의 구성에 액세스합니다.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

appsettings.json 앞의 예제에서는 다음을 수행합니다.

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

대리자로 옵션 구성

대리자에서 구성된 옵션은 구성 공급자에 설정된 값을 재정의합니다.

다음 코드에서 IConfigureOptions<TOptions> 서비스가 서비스 컨테이너에 추가됩니다. MyOptions의 값을 구성하는 데 대리자를 사용합니다.

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

다음 코드는 다음과 같은 옵션 값을 표시합니다.

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

위의 예제에서 Option1Option2의 값은 모두 appsettings.json에서 지정되고 구성된 대리자에 의해 재정의됩니다.

호스트 대 앱 구성

앱을 구성하고 시작하기 전에 호스트를 구성하고 시작합니다. 호스트는 앱 시작 및 수명 관리를 담당합니다. 앱과 호스트 모두 이 항목에서 설명하는 구성 관리자를 사용하여 구성합니다. 호스트 구성 키-값 쌍은 앱의 구성에도 포함됩니다. 호스트를 빌드할 때 구성 공급자를 사용하는 방법과 구성 소스가 호스트 구성에 미치는 영향에 대한 자세한 내용은 ASP.NET Core 기본 사항 개요를 참조하세요.

기본 호스트 구성

웹 호스트를 사용하는 경우 기본 구성에 대한 자세한 내용은 이 항목의 ASP.NET Core 2.2 버전을 참조하세요.

  • 호스트 구성은 다음에서 제공됩니다.
  • 웹 호스트 기본 구성이 설정됨(ConfigureWebHostDefaults):
    • Kestrel은 웹 서버로 사용되며 앱의 구성 공급자를 사용하여 구성됩니다.
    • 호스트 필터링 미들웨어를 추가합니다.
    • ASPNETCORE_FORWARDEDHEADERS_ENABLED 환경 변수가 true로 설정된 경우 전달된 헤더 미들웨어를 추가합니다.
    • IIS 통합을 사용하도록 설정합니다.

기타 구성

이 항목에서는 앱 구성에 관련된 내용만 다룹니다. ASP.NET Core 앱을 실행하고 호스팅하는 다른 요소는 이 항목에서 다루지 않는 구성 파일을 사용하여 구성됩니다.

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

이전 버전의 ASP.NET 앱 구성을 마이그레이션하는 방법에 대한 자세한 내용은 ASP.NET ASP.NET Core로 업데이트를 참조 하세요.

외부 어셈블리의 구성 추가

IHostingStartup 구현은 시작 시 앱의 Startup 클래스 외부에 있는 외부 어셈블리에서 앱에 향상된 기능을 추가할 수 있습니다. 자세한 내용은 ASP.NET Core에서 호스팅 시작 어셈블리 사용을 참조하세요.

구성 바인딩 소스 생성기

구성 바인딩 원본 생성기는 AOT 및 트리밍 친화적인 구성을 제공합니다. 자세한 내용은 구성 바인딩 원본 생성기를 참조 하세요.

추가 리소스

ASP.NET Core에서 애플리케이션 구성은 하나 이상의 구성 공급자를 사용하여 수행합니다. 구성 공급자는 다음과 같은 다양한 구성 소스를 사용하여 키-값 쌍에서 구성 데이터를 읽습니다.

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

이 문서에서는 ASP.NET Core의 구성에 대한 정보를 제공합니다. 콘솔 앱에서 구성을 사용하는 방법에 대한 자세한 내용은 .NET 구성을 참조하세요.

애플리케이션 및 호스트 구성

ASP.NET Core 앱은 호스트를 구성 및 실행합니다. 호스트는 앱 시작 및 수명 관리를 담당합니다. ASP.NET Core 템플릿은 호스트를 포함하는 WebApplicationBuilder을(를) 만듭니다. 일부 구성은 호스트와 애플리케이션 구성 공급자 모두에서 수행할 수 있지만 일반적으로 호스트에 필요한 구성만 호스트 구성에서 수행해야 합니다.

애플리케이션 구성은 우선 순위가 가장 높으며 다음 섹션에 자세히 설명되어 있습니다. 호스트 구성은 애플리케이션 구성을 따르며 이 문서에 설명되어 있습니다.

기본 애플리케이션 구성 원본

dotnet new 또는 Visual Studio를 사용하여 만든 ASP.NET Core 웹앱은 다음 코드를 생성합니다.

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder는 미리 구성된 기본값을 사용하여 WebApplicationBuilder 클래스의 새 인스턴스를 초기화합니다. 초기화된 WebApplicationBuilder(builder)은(는) 가장 높은 우선 순위부터 가장 낮은 우선 순위까지 다음 순서로 앱의 기본 구성을 제공합니다.

  1. 명령줄 구성 공급자를 사용하는 명령줄 인수
  2. 접두사 없는 환경 변수 구성 공급자를 사용하는 접두사 없는 환경 변수.
  3. 사용자 비밀 - 앱이 Development 환경에서 실행되는 경우.
  4. JSON 구성 공급자를 사용하는 appsettings.{Environment}.json. 예를 들어 appsettings.Production.jsonappsettings.Development.json를 지정합니다.
  5. JSON 구성 공급자를 사용하는appsettings.json.
  6. 다음 섹션에 설명된 호스트 구성에 대한 대체입니다.

기본 호스트 구성 원본

다음 목록에는 가장 높은 우선 순위에서 WebApplicationBuilder에 대한 가장 낮은 우선 순위까지의 기본 호스트 구성 원본이 포함되어 있습니다.

  1. 명령줄 구성 공급자를 사용하는 명령줄 인수
  2. 환경 변수 구성 공급자를 사용하는 DOTNET_ 접두사가 붙은 환경 변수.
  3. 환경 변수 구성 공급자를 사용하는 ASPNETCORE_ 접두사가 붙은 환경 변수.

.NET 제네릭 호스트웹 호스트의 경우, 기본 호스트 구성 원본을 가장 높은 우선 순위에서 가장 낮은 우선 순위로 지정합니다.

  1. 환경 변수 구성 공급자를 사용하는 ASPNETCORE_ 접두사가 붙은 환경 변수.
  2. 명령줄 구성 공급자를 사용하는 명령줄 인수
  3. 환경 변수 구성 공급자를 사용하는 DOTNET_ 접두사가 붙은 환경 변수.

구성 값이 호스트 및 애플리케이션 구성에서 설정되면 애플리케이션 구성이 사용됩니다.

호스트 변수

다음 변수는 호스트 작성기를 초기화할 떄 조기에 잠기므로 애플리케이션 구성의 영향을 받을 수 없습니다.

다른 모든 호스트 설정은 호스트 구성 대신 애플리케이션 구성에서 읽습니다.

URLS은(는) 부트스트랩 설정이 아닌 많은 일반적인 호스트 설정 중 하나입니다. 이전 목록에 없는 다른 모든 호스트 설정과 마찬가지로 URLS은(는) 나중에 애플리케이션 구성에서 읽습니다. 호스트 구성은 애플리케이션 구성에 대한 대체이므로 호스트 구성을 사용하여 URLS을(를) 설정할 수 있지만 애플리케이션 구성의 구성 원본(예: appsettings.json)에 의해 재정의됩니다.

자세한 내용은 콘텐츠 루트, 앱 이름 및 환경 변경환경 변수 또는 명령줄별 콘텐츠 루트, 앱 이름 및 환경 변경을 참조하세요.

이 문서의 나머지 섹션은 애플리케이션 구성을 참조합니다.

애플리케이션 구성 공급자

다음 코드는 추가된 순서대로 사용하도록 설정된 구성 공급자를 표시합니다.

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

우선 순위가 가장 높은 기본 구성 원본의 이전 목록은 공급자가 템플릿 생성 애플리케이션에 추가되는 순서와 반대 순서로 공급자를 표시합니다. 예를 들어 JSON 구성 공급자명령줄 구성 공급자 앞에 추가됩니다.

나중에 추가되는 구성 공급자는 가장 높은 우선 순위를 가지므로 이전 키 설정을 재정의합니다. 예를 들어 MyKeyappsettings.json과 환경 모두에서 설정된 경우 환경 값이 사용됩니다. 명령줄 구성 공급자는 기본 구성 공급자를 사용하여 다른 모든 공급자를 재정의합니다.

CreateBuilder에 대한 자세한 내용은 기본 작성기 설정을 참조하세요.

appsettings.json

다음 appsettings.json 파일을 살펴보세요.

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

기본 JsonConfigurationProvider는 다음과 같은 순서로 구성을 로드합니다.

  1. appsettings.json
  2. appsettings.{Environment}.json : 예를 들어 appsettings.Production.jsonappsettings.Development.json 파일입니다. 파일 IHostingEnvironment.EnvironmentName의 환경 버전은 . 자세한 내용은 ASP.NET Core에서 여러 환경 사용을 참조하세요.

appsettings.{Environment}.json 값은 appsettings.json의 키를 재정의합니다. 예를 들어 기본적으로 다음과 같습니다.

  • 개발 환경에서는 appsettings.Development.json 구성이 appsettings.json에서 찾은 값을 덮어씁니다.
  • 프로덕션 환경에서는 appsettings.Production.json 구성이 appsettings.json에서 찾은 값을 덮어씁니다. Azure에 앱을 배포하는 경우를 예로 들 수 있습니다.

구성 값을 보장해야 하는 경우 GetValue를 참조 하십시오. 위의 예제에서는 문자열만 읽고 기본값을 지원하지 않습니다.

기본 구성을 사용하여 appsettings.jsonappsettings.{Environment}.json 파일은 reloadOnChange: true를 통해 사용하도록 설정됩니다. 앱이 시작된 appsettings.jsonappsettings.{Environment}.json 파일에 대한 변경 내용은 JSON 구성 공급자에서 읽습니다.

appsettings.json의 주석

appsettings.jsonappsettings.{Environment}.json파일의 주석은 JavaScript 또는 C# 스타일 주석을 사용하여 지원됩니다.

옵션 패턴을 사용하여 계층적 구성 데이터 바인딩

관련 구성 값을 읽는 기본 방법은 옵션 패턴를 사용하는 것입니다. 예를 들어 다음 구성 값을 읽으려면:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

다음 PositionOptions 클래스를 만듭니다.

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

옵션 클래스:

  • 매개 변수가 없는 public 생성자를 사용하는 비추상이어야 합니다.
  • 형식의 모든 공용 읽기-쓰기 속성이 바인딩됩니다.
  • 필드가 바인딩되지 않습니다. 위 코드에서 Position은 바운딩되지 않습니다. Position 필드를 사용하므로 클래스를 구성 공급자에 바인딩할 때 문자열 "Position"을 앱에서 하드 코딩하지 않아도 됩니다.

코드는 다음과 같습니다.

  • ConfigurationBinder.Bind를 호출하여 PositionOptions 클래스를 Position 섹션에 바인딩합니다.
  • Position 구성 데이터를 표시합니다.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

위 코드에서는 기본적으로 앱을 시작한 후의 JSON 구성 파일의 변경 사항을 읽습니다.

ConfigurationBinder.Get<T>는 지정된 형식을 바인딩하고 반환합니다. ConfigurationBinder.Get<T>ConfigurationBinder.Bind를 사용하는 것보다 편리할 수 있습니다. 다음 코드에서는 ConfigurationBinder.Get<T>PositionOptions 클래스를 함께 사용하는 방법을 보여 줍니다.

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

위 코드에서는 기본적으로 앱을 시작한 후의 JSON 구성 파일의 변경 사항을 읽습니다.

옵션 패턴을 사용하는 경우 한 가지 대체 방법은 Position 섹션을 바인딩하고 종속성 주입 서비스 컨테이너에 추가하는 것입니다. 다음 코드에서 PositionOptionsConfigure를 통해 서비스 컨테이너에 추가되고 구성에 바인딩됩니다.

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

위의 코드를 사용하여 다음 코드는 위치 옵션을 읽습니다.

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

위 코드에서는 앱을 시작한 후의 JSON 구성 파일의 변경 사항은 읽지 않습니다. 앱을 시작한 후의 변경 사항을 읽으려면 IOptionsSnapshot을 사용합니다.

기본 구성을 사용하여 appsettings.jsonappsettings.{Environment}.json 파일은 reloadOnChange: true를 통해 사용하도록 설정됩니다. 앱이 시작된 appsettings.jsonappsettings.{Environment}.json 파일에 대한 변경 내용은 JSON 구성 공급자에서 읽습니다.

추가 JSON 구성 파일 추가에 대한 자세한 내용은 이 문서의 JSON 구성 공급자를 참조하세요.

서비스 컬렉션 결합

서비스를 등록하고 옵션을 구성하는 다음 메서드를 고려합니다.

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

관련 등록 그룹을 확장 메서드로 이동하여 서비스를 등록할 수 있습니다. 예를 들어, 구성 서비스는 다음 클래스에 추가됩니다.

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

나머지 서비스는 유사한 클래스에 등록됩니다. 다음 코드는 새 확장 메서드를 사용하여 서비스를 등록합니다.

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

참고:services.Add{GROUP_NAME} 확장 메서드는 서비스를 추가하고 잠재적으로 구성합니다. 예를 들어 AddControllersWithViews는 보기에 필요한 서비스 MVC 컨트롤러를 추가하고 AddRazorPages는 Razor Pages에 필요한 서비스를 추가합니다.

보안 및 사용자 비밀

구성 데이터 지침:

  • 구성 공급자 코드 또는 일반 텍스트 구성 파일에 암호 또는 기타 중요한 데이터를 절대 저장하지 마세요. 비밀 관리자 도구를 사용하여 개발에 사용되는 비밀을 저장할 수 있습니다.
  • 개발 또는 테스트 환경에서 프로덕션 비밀을 사용하지 마세요.
  • 의도치 않게 소스 코드 리포지토리에 커밋되는 일이 없도록 프로젝트 외부에서 비밀을 지정하세요.

기본적으로, 사용자 비밀 구성 원본은 JSON 구성 원본 뒤에 등록됩니다. 따라서 사용자 비밀 키가 appsettings.jsonappsettings.{Environment}.json의 키보다 우선합니다.

암호 또는 기타 중요한 데이터 저장에 대한 자세한 정보:

Azure Key Vault가 ASP.NET Core 앱에 대한 앱 비밀을 안전하게 저장합니다. 자세한 내용은 ASP.NET Core의 Azure Key Vault 구성 공급자를 참조하세요.

접두사가 없는 환경 변수

접두사가 없는 환경 변수는 ASPNETCORE_ 또는 DOTNET_ 접두사가 붙은 변수가 아니라 환경 변수입니다. 예를 들어, ASP.NET Core 웹 애플리케이션 템플릿은 launchSettings.json에서 "ASPNETCORE_ENVIRONMENT": "Development"을 설정합니다. ASPNETCORE_DOTNET_ 환경 변수에 대한 자세한 내용은 다음을 참조하세요.

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

: 구분 기호는 모든 플랫폼의 환경 변수 계층적 키에서 작동하지 않습니다. 이중 밑줄 __은 다음과 같습니다.

  • 모든 플랫폼에서 지원됩니다. 예를 들어 : 구분 기호는 Bash에서 지원되지 않지만 __은 지원됩니다.
  • 자동으로 :으로 대체

다음 set 명령은,

  • Windows에서 위의 예제에 나오는 환경 키 및 값을 설정합니다.
  • 샘플 다운로드를 사용하는 경우 설정을 테스트합니다. dotnet run 명령은 프로젝트 디렉터리에서 실행해야 합니다.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

위의 환경 설정은,

  • 설정된 명령 창에서 시작된 프로세스에서만 설정됩니다.
  • Visual Studio에서 시작된 브라우저에서는 읽을 수 없습니다.

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

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

위의 명령이 appsettings.jsonappsettings.{Environment}.json을 재정의하는지 테스트하려면:

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

환경 변수의 접두사를 지정하는 문자열을 사용하여 AddEnvironmentVariables를 호출합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

var app = builder.Build();

위의 코드에서

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

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

다음 명령은 사용자 지정 접두사를 테스트합니다.

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

기본 구성DOTNET_ASPNETCORE_ 접두사가 붙은 환경 변수 및 명령줄 인수를 로드합니다. DOTNET_ASPNETCORE_ 접두사는 ASP.NET Core에서 호스트 및 앱 구성에 사용되지만, 사용자 구성에는 사용되지 않습니다. 호스트 및 앱 구성에 대한 자세한 내용은 .NET 제네릭 호스트를 참조하세요.

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

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

자세한 내용은 Azure 앱: Azure Portal을 사용하여 앱 구성 재정의를 참조하세요.

Azure 데이터베이스 연결 문자열에 대한 자세한 내용은 연결 문자열 접두사를 참조하세요.

환경 변수 명명

환경 변수의 이름은 appsettings.json 파일의 구조를 반영합니다. 계층 구조의 각 요소는 이중 밑줄(권장) 또는 콜론으로 구분됩니다. 요소 구조에 배열이 포함된 경우, 해당 배열 인덱스는 이 경로의 추가 요소 이름으로 처리되어야 합니다. 다음 appsettings.json 파일 및 환경 변수라고 표시된 해당 값을 살펴보세요.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

환경 변수

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

생성된 launchSettings.json에 설정된 환경 변수

설정된 launchSettings.json 환경 변수는 시스템 환경에서 설정된 변수를 재정의합니다. 예를 들어 ASP.NET Core 웹 템플릿은 엔드포인트 구성을 다음으로 launchSettings.json 설정하는 파일을 생성합니다.

"applicationUrl": "https://localhost:5001;http://localhost:5000"

applicationUrl 구성은 ASPNETCORE_URLS 환경 변수를 설정하고 환경에 설정된 값을 재정의합니다.

Linux에서 환경 변수 이스케이프

Linux에서는 URL 환경 변수의 값을 이스케이프 처리하여 systemd가 구문 분석을 할 수 있도록 해야 합니다. http:--localhost:5001을 생성하는 Linux 도구 systemd-escape를 사용하세요.

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

환경 변수 표시

다음 코드는 애플리케이션 시작 시 환경 설정을 디버그할 때 도움이 될 수 있는 환경 변수 및 값을 표시합니다.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

명령줄

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

  • appsettings.jsonappsettings.{Environment}.json 파일입니다.
  • 개발 환경의 앱 비밀.
  • 환경 변수입니다.

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

명령줄 인수

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

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

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

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

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

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

키 값은,

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

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

스위치 매핑

스위치 매핑은 이름 교체 논리를 지원합니다. AddCommandLine 메서드에 스위치 교체 사전을 제공합니다.

스위치 매핑 사전을 사용하면 명령줄 인수를 통해 제공된 키와 일치하는 키에 대해 사전을 검사합니다. 사전에서 명령줄 키가 발견되면 사전 값이 다시 전달되어 앱 구성의 키-값 쌍이 설정됩니다. 단일 대시(-) 접두사가 붙은 명령줄 키에는 스위치 매핑이 필수입니다.

스위치 매핑 사전 키 규칙:

  • 스위치는 - 또는 --으로 시작해야 합니다.
  • 스위치 매핑 사전이 중복 키를 포함하면 안 됩니다.

스위치 매핑 사전을 사용하려면 AddCommandLine에 대한 호출에 전달합니다.


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

다음 명령을 실행하여 키 교체를 테스트합니다.

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

다음 코드는 교체된 키의 키 값을 보여 줍니다.

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

스위치 매핑을 사용하는 앱의 경우 CreateDefaultBuilder에 대한 호출은 인수를 전달하지 않아야 합니다. CreateDefaultBuilder 메서드의 AddCommandLine 호출에는 매핑된 스위치가 포함되지 않으며 CreateDefaultBuilder에 스위치 매핑 사전을 전달할 방법은 없습니다. 해결 방법으로 CreateDefaultBuilder에 인수를 전달하지 않고 대신 ConfigurationBuilder 메서드의 AddCommandLine 메서드에서 인수와 스위치 매핑 사전을 모두 처리하도록 할 수 있습니다.

Visual Studio에서 환경 및 명령줄 인수 설정

Visual Studio의 시작 프로필 대화 상자에서 환경 및 명령줄 인수를 설정할 수 있습니다.

  • 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.
  • 디버그 > 일반 탭을 선택하고 디버그 시작 프로필 UI 열기를 선택합니다.

계층적 구성 데이터

구성 API는 구성 키에 구분 기호를 사용해 계층적 데이터를 평면화하여 계층적 구성 데이터를 읽습니다.

샘플 다운로드에는 다음 appsettings.json 파일이 포함되어 있습니다.

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

샘플 다운로드의 다음 코드는 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

계층적 구성 데이터를 읽는 기본 방법은 옵션 패턴을 사용하는 것입니다. 자세한 내용은 이 문서의 계층적 구성 데이터 바인딩을 참조하세요.

구성 데이터에서는 GetSectionGetChildren 메서드를 사용하여 섹션과 섹션의 자식을 격리할 수 있습니다. 이러한 메서드에 대해서는 나중에 GetSection, GetChildren 및 Exists에서 설명합니다.

구성 키 및 값

구성 키는,

  • 대/소문자를 구분하지 않습니다. 예를 들어 ConnectionStringconnectionstring은 동일한 키로 처리됩니다.
  • 둘 이상의 구성 공급자에서 키와 값이 설정된 경우 추가된 마지막 공급자의 값이 사용됩니다. 자세한 내용은 기본 구성을 참조하세요.
  • 계층적 키
    • 구성 API 내에서는 콜론 구분 기호(:)가 모든 플랫폼에 적용됩니다.
    • 환경 변수에서는 콜론 구분 기호가 일부 플랫폼에 적용되지 않을 수 있습니다. 두 개의 밑줄(__)은 모든 플랫폼에서 지원되며 콜론(:)으로 자동 변환됩니다.
    • Azure Key Vault에서 계층적 키는 --를 구분 기호로 사용합니다. Azure Key Vault 구성 공급자는 암호를 앱의 구성으로 로드할 때 --를 자동으로 :으로 바꿉니다.
  • ConfigurationBinder는 구성 키에 배열 인덱스를 사용하여 배열을 개체에 바인딩하는 것을 지원합니다. 배열 바인딩에 대해서는 클래스에 배열 바인딩 섹션에서 설명합니다.

구성 값은,

  • 문자열입니다.
  • Null 값은 구성에 저장하거나 개체에 바인딩할 수 없습니다.

구성 공급자

다음 표에서는 ASP.NET Core 앱에서 사용할 수 있는 구성 공급자를 보여 줍니다.

공급자 다음에서 구성 제공
Azure Key Vault 구성 공급자 Azure Key Vault
Azure 앱 구성 공급자 Azure App Configuration
명령줄 구성 공급자 명령줄 매개 변수
사용자 지정 구성 공급자 사용자 지정 소스
환경 변수 구성 공급자 환경 변수
파일 구성 공급자 INI, JSON 및 XML 파일
파일별 키 구성 공급자 디렉터리 파일
메모리 구성 공급자 메모리 내 컬렉션
사용자 비밀 사용자 프로필 디렉터리의 파일

구성 공급자에서 지정한 순서로 구성 소스를 읽습니다. 앱에 필요한 기본 구성 소스에 대한 우선 순위에 맞게 구성 공급자를 코드에 정렬하세요.

구성 공급자의 일반적인 순서는 다음과 같습니다.

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. 사용자 비밀
  4. 환경 변수 구성 공급자를 사용하는 환경 변수
  5. 명령줄 구성 공급자를 사용하는 명령줄 인수

일반적인 방식은 명령줄 구성 공급자를 일련의 공급자에서 마지막에 추가하는 것이므로, 다른 공급자에서 설정한 구성을 명령줄 인수로 재정의할 수 있습니다.

위의 공급자 시퀀스는 기본 구성에서 사용됩니다.

연결 문자열 접두사

구성 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

파일 구성 공급자

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

INI 구성 공급자

IniConfigurationProvider는 런타임에 INI 파일 키-값 쌍에서 구성을 로드합니다.

다음 코드는 여러 구성 공급자를 추가합니다.

var builder = WebApplication.CreateBuilder(args);

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

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

위의 코드에서 MyIniConfig.iniMyIniConfig.{Environment}.ini 파일의 설정은 다음의 설정에 의해 재정의됩니다.

샘플 다운로드에는 다음 MyIniConfig.ini 파일이 포함되어 있습니다.

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

JSON 구성 공급자

JsonConfigurationProvider은(는) JSON 파일 키-값 쌍에서 구성을 로드합니다.

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

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

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

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

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

일반적으로 사용자 지정 JSON 파일은 환경 변수 구성 공급자명령줄 구성 공급자에 설정된 값을 재정의하지 않습니다.

XML 구성 공급자

XmlConfigurationProvider는 런타임에 XML 파일 키-값 쌍에서 구성을 로드합니다.

다음 코드는 여러 구성 공급자를 추가합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

위의 코드에서 MyXMLFile.xmlMyXMLFile.{Environment}.xml 파일의 설정은 다음의 설정에 의해 재정의됩니다.

샘플 다운로드에는 다음 MyXMLFile.xml 파일이 포함되어 있습니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

같은 요소 이름을 사용하는 반복 요소는 다음과 같이 name 특성을 사용하여 요소를 구분하면 작동합니다.

<?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>

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

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

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

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

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

  • key:attribute
  • section:key:attribute

파일별 키 구성 공급자

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

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

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

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

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

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

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

메모리 구성 공급자

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

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

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

샘플 다운로드의 다음 코드는 위의 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

위의 코드에서 config.AddInMemoryCollection(Dict)기본 구성 공급자 뒤에 추가됩니다. 구성 공급자 순서 지정 예제는 JSON 구성 공급자를 참조하세요.

MemoryConfigurationProvider를 사용하는 또 다른 예제는 배열 바인딩을 참조하세요.

Kestrel 엔드포인트 구성

Kestrel 관련 엔드포인트 구성은 모든 서버 간 엔드포인트 구성을 재정의합니다. 서버 간 엔드포인트 구성에는 다음이 포함됩니다.

ASP.NET Core 웹 앱에서 사용되는 다음 appsettings.json 파일을 고려합니다.

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

위에 강조 표시된 마크업을 ASP.NET Core 웹앱에 사용하면서 다음과 같은 서버 간 엔드포인트 구성을 사용하여 명령줄에서 앱을 시작하는 경우,

dotnet run --urls="https://localhost:7777"

Kestrel은 https://localhost:7777이 아닌 appsettings.json 파일(https://localhost:9999)에서 Kestrel용으로 특별히 구성된 엔드포인트에 바인딩합니다.

환경 변수로 구성된 Kestrel 관련 엔드포인트를 고려합니다.

set Kestrel__Endpoints__Https__Url=https://localhost:8888

위 환경 변수에서 Https는 Kestrel 관련 엔드포인트의 이름입니다. 또한 위 appsettings.json 파일은 Https라는 Kestrel 관련 엔드포인트를 정의합니다. 기본적으로환경 변수 구성 공급자를 사용하는 환경 변수는 appsettings.{Environment}.json 이후에 읽혀지므로 위 환경 변수는 Https 엔드포인트에 사용됩니다.

GetValue

ConfigurationBinder.GetValue는 지정된 키를 사용하여 구성에서 단일 값을 추출하고 해당 값을 지정된 형식으로 변환합니다.

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

위의 코드에서 구성에 NumberKey가 없는 경우 기본값 99가 사용됩니다.

GetSection, GetChildren 및 Exists

이어지는 예제에서는 다음 MySubsection.json 파일을 고려하세요.

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

다음 코드는 구성 공급자에 추가 MySubsection.json 됩니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection 는 지정된 하위 섹션 키가 있는 구성 하위 섹션을 반환합니다.

다음 코드는 section1의 값을 반환합니다.

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

다음 코드는 section2:subsection0의 값을 반환합니다.

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSectionnull을 반환하지 않습니다. 일치하는 섹션을 찾을 수 없으면 빈 IConfigurationSection이 반환됩니다.

GetSection이 일치하는 섹션을 반환할 때 Value는 채워지지 않습니다. 섹션이 존재하면 KeyPath가 반환됩니다.

GetChildren 및 Exists

다음 코드는 다음에 대한 section2:subsection0값을 호출 IConfiguration.GetChildren 하고 반환합니다.

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

이전 코드는 섹션이 있는지 확인하기 위해 호출 ConfigurationExtensions.Exists 합니다.

배열 바인딩

ConfigurationBinder.Bind는 구성 키에 배열 인덱스를 사용하여 배열을 개체에 바인딩하는 것을 지원합니다. 숫자 키 세그먼트를 노출하는 모든 배열 형식은 POCO 클래스 배열에 배열을 바인딩할 수 있습니다.

샘플 다운로드고려합니다MyArray.json.

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

다음 코드는 구성 공급자에 추가 MyArray.json 됩니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

다음 코드는 구성을 읽고 값을 표시합니다.

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

위의 코드는 다음 출력을 반환합니다.

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

위의 출력에서 Index 3은 MyArray.json"4": "value40",에 해당하는 value40 값을 가집니다. 바인딩된 배열 인덱스는 연속되며 구성 키 인덱스에 바인딩되지 않습니다. 구성 바인더는 null 값을 바인딩하거나 바인딩된 개체에 null 항목을 만들 수 없습니다.

사용자 지정 구성 공급자

샘플 앱에서는 EF(Entity Framework)를 사용하여 데이터베이스에서 구성 키-값 쌍을 읽는 기본 구성 공급자를 만드는 방법을 보여 줍니다.

이 공급자의 특징은 다음과 같습니다.

  • 데모용으로 EF 메모리 내 데이터베이스를 사용합니다. 연결 문자열이 필요한 데이터베이스를 사용하려면 보조 ConfigurationBuilder를 구현하여 다른 구성 공급자에서 연결 문자열을 제공하세요.
  • 이 공급자는 시작 시 데이터베이스 테이블을 구성으로 읽어 들입니다. 이 공급자는 키별 기준으로 데이터베이스를 쿼리하지 않습니다.
  • 변경 시 다시 로드가 구현되지 않으므로 앱 시작 후 데이터베이스를 업데이트해도 앱 구성에 영향을 주지 않습니다.

데이터베이스에 구성 값을 저장하는 EFConfigurationValue 엔터티를 정의합니다.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

구성된 값을 저장 및 액세스하는 EFConfigurationContext를 추가합니다.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

IConfigurationSource를 구현하는 클래스를 만듭니다.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

ConfigurationProvider에서 상속하여 사용자 지정 구성 공급자를 만듭니다. 구성 공급자는 비어 있는 데이터베이스를 초기화합니다. 구성 키는 대/소문자를 구분하지 않으므로 데이터베이스를 초기화하는 데 사용되는 사전은 대/소문자를 구분하지 않는 비교자(StringComparer.OrdinalIgnoreCase)를 사용하여 생성됩니다.

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

AddEFConfiguration 확장 메서드를 사용하여 구성 소스를 ConfigurationBuilder에 추가할 수 있습니다.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

다음 코드는 다음에서 사용자 지정 EFConfigurationProvider 을 사용하는 방법을 보여줍니다.Program.cs

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

DI(종속성 주입)를 통해 구성에 액세스

IConfiguration 서비스를 확인하여 DI(종속성 주입)를 사용하여 구성을 서비스에 주입할 수 있습니다.

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

IConfiguration을 사용하여 값에 액세스하는 방법에 대한 내용은 이 문서의 GetValueGetSection, GetChildren 및 Exists를 참조하세요.

Razor Pages의 구성 액세스

다음 코드는 Razor 페이지의 구성 데이터를 표시합니다.

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

다음 코드에서 MyOptionsConfigure를 통해 서비스 컨테이너에 추가되고 구성에 바인딩됩니다.

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

다음 태그는 지시문을 @injectRazor 사용하여 옵션 값을 확인하고 표시합니다.

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

MVC 뷰 파일의 구성 액세스

다음 코드는 MVC 뷰의 구성 데이터를 표시합니다.

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Program.cs의 구성 액세스

다음 코드는 Program.cs 파일의 구성에 액세스합니다.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

appsettings.json 앞의 예제에서는 다음을 수행합니다.

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

대리자로 옵션 구성

대리자에서 구성된 옵션은 구성 공급자에 설정된 값을 재정의합니다.

다음 코드에서 IConfigureOptions<TOptions> 서비스가 서비스 컨테이너에 추가됩니다. MyOptions의 값을 구성하는 데 대리자를 사용합니다.

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

다음 코드는 다음과 같은 옵션 값을 표시합니다.

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

위의 예제에서 Option1Option2의 값은 모두 appsettings.json에서 지정되고 구성된 대리자에 의해 재정의됩니다.

호스트 대 앱 구성

앱을 구성하고 시작하기 전에 호스트를 구성하고 시작합니다. 호스트는 앱 시작 및 수명 관리를 담당합니다. 앱과 호스트 모두 이 항목에서 설명하는 구성 관리자를 사용하여 구성합니다. 호스트 구성 키-값 쌍은 앱의 구성에도 포함됩니다. 호스트를 빌드할 때 구성 공급자를 사용하는 방법과 구성 소스가 호스트 구성에 미치는 영향에 대한 자세한 내용은 ASP.NET Core 기본 사항 개요를 참조하세요.

기본 호스트 구성

웹 호스트를 사용하는 경우 기본 구성에 대한 자세한 내용은 이 항목의 ASP.NET Core 2.2 버전을 참조하세요.

  • 호스트 구성은 다음에서 제공됩니다.
  • 웹 호스트 기본 구성이 설정됨(ConfigureWebHostDefaults):
    • Kestrel은 웹 서버로 사용되며 앱의 구성 공급자를 사용하여 구성됩니다.
    • 호스트 필터링 미들웨어를 추가합니다.
    • ASPNETCORE_FORWARDEDHEADERS_ENABLED 환경 변수가 true로 설정된 경우 전달된 헤더 미들웨어를 추가합니다.
    • IIS 통합을 사용하도록 설정합니다.

기타 구성

이 항목에서는 앱 구성에 관련된 내용만 다룹니다. ASP.NET Core 앱을 실행하고 호스팅하는 다른 요소는 이 항목에서 다루지 않는 구성 파일을 사용하여 구성됩니다.

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

이전 버전의 ASP.NET 앱 구성을 마이그레이션하는 방법에 대한 자세한 내용은 ASP.NET ASP.NET Core로 업데이트를 참조 하세요.

외부 어셈블리의 구성 추가

IHostingStartup 구현은 시작 시 앱의 Startup 클래스 외부에 있는 외부 어셈블리에서 앱에 향상된 기능을 추가할 수 있습니다. 자세한 내용은 ASP.NET Core에서 호스팅 시작 어셈블리 사용을 참조하세요.

추가 리소스

ASP.NET Core에서 애플리케이션 구성은 하나 이상의 구성 공급자를 사용하여 수행합니다. 구성 공급자는 다음과 같은 다양한 구성 소스를 사용하여 키-값 쌍에서 구성 데이터를 읽습니다.

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

이 문서에서는 ASP.NET Core의 구성에 대한 정보를 제공합니다. 콘솔 앱에서 구성을 사용하는 방법에 대한 자세한 내용은 .NET 구성을 참조하세요.

애플리케이션 및 호스트 구성

ASP.NET Core 앱은 호스트를 구성 및 실행합니다. 호스트는 앱 시작 및 수명 관리를 담당합니다. ASP.NET Core 템플릿은 호스트를 포함하는 WebApplicationBuilder을(를) 만듭니다. 일부 구성은 호스트와 애플리케이션 구성 공급자 모두에서 수행할 수 있지만 일반적으로 호스트에 필요한 구성만 호스트 구성에서 수행해야 합니다.

애플리케이션 구성은 우선 순위가 가장 높으며 다음 섹션에 자세히 설명되어 있습니다. 호스트 구성은 애플리케이션 구성을 따르며 이 문서에 설명되어 있습니다.

기본 애플리케이션 구성 원본

dotnet new 또는 Visual Studio를 사용하여 만든 ASP.NET Core 웹앱은 다음 코드를 생성합니다.

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder는 미리 구성된 기본값을 사용하여 WebApplicationBuilder 클래스의 새 인스턴스를 초기화합니다. 초기화된 WebApplicationBuilder(builder)은(는) 가장 높은 우선 순위부터 가장 낮은 우선 순위까지 다음 순서로 앱의 기본 구성을 제공합니다.

  1. 명령줄 구성 공급자를 사용하는 명령줄 인수
  2. 접두사 없는 환경 변수 구성 공급자를 사용하는 접두사 없는 환경 변수.
  3. 사용자 비밀 - 앱이 Development 환경에서 실행되는 경우.
  4. JSON 구성 공급자를 사용하는 appsettings.{Environment}.json. 예를 들어 appsettings.Production.jsonappsettings.Development.json를 지정합니다.
  5. JSON 구성 공급자를 사용하는appsettings.json.
  6. 다음 섹션에 설명된 호스트 구성에 대한 대체입니다.

기본 호스트 구성 원본

다음 목록에는 가장 높은 우선 순위에서 가장 낮은 우선 순위까지의 기본 호스트 구성 원본이 포함되어 있습니다.

  1. 환경 변수 구성 공급자를 사용하는 ASPNETCORE_ 접두사가 붙은 환경 변수.
  2. 명령줄 구성 공급자를 사용하는 명령줄 인수
  3. 환경 변수 구성 공급자를 사용하는 DOTNET_ 접두사가 붙은 환경 변수.

구성 값이 호스트 및 애플리케이션 구성에서 설정되면 애플리케이션 구성이 사용됩니다.

호스트 구성 에서 접두사 환경 변수가 명령줄 인수보다 우선 순위가 높은 이유에 대한 설명은 이 GitHub 주석의 설명을ASPNETCORE_ 참조하세요.

호스트 변수

다음 변수는 호스트 작성기를 초기화할 떄 조기에 잠기므로 애플리케이션 구성의 영향을 받을 수 없습니다.

다른 모든 호스트 설정은 호스트 구성 대신 애플리케이션 구성에서 읽습니다.

URLS은(는) 부트스트랩 설정이 아닌 많은 일반적인 호스트 설정 중 하나입니다. 이전 목록에 없는 다른 모든 호스트 설정과 마찬가지로 URLS은(는) 나중에 애플리케이션 구성에서 읽습니다. 호스트 구성은 애플리케이션 구성에 대한 대체이므로 호스트 구성을 사용하여 URLS을(를) 설정할 수 있지만 애플리케이션 구성의 구성 원본(예: appsettings.json)에 의해 재정의됩니다.

자세한 내용은 콘텐츠 루트, 앱 이름 및 환경 변경환경 변수 또는 명령줄별 콘텐츠 루트, 앱 이름 및 환경 변경을 참조하세요.

이 문서의 나머지 섹션은 애플리케이션 구성을 참조합니다.

애플리케이션 구성 공급자

다음 코드는 추가된 순서대로 사용하도록 설정된 구성 공급자를 표시합니다.

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

우선 순위가 가장 높은 기본 구성 원본의 이전 목록은 공급자가 템플릿 생성 애플리케이션에 추가되는 순서와 반대 순서로 공급자를 표시합니다. 예를 들어 JSON 구성 공급자명령줄 구성 공급자 앞에 추가됩니다.

나중에 추가되는 구성 공급자는 가장 높은 우선 순위를 가지므로 이전 키 설정을 재정의합니다. 예를 들어 MyKeyappsettings.json과 환경 모두에서 설정된 경우 환경 값이 사용됩니다. 명령줄 구성 공급자는 기본 구성 공급자를 사용하여 다른 모든 공급자를 재정의합니다.

CreateBuilder에 대한 자세한 내용은 기본 작성기 설정을 참조하세요.

appsettings.json

다음 appsettings.json 파일을 살펴보세요.

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

기본 JsonConfigurationProvider는 다음과 같은 순서로 구성을 로드합니다.

  1. appsettings.json
  2. appsettings.{Environment}.json : 예를 들어 appsettings.Production.jsonappsettings.Development.json 파일입니다. 파일 IHostingEnvironment.EnvironmentName의 환경 버전은 . 자세한 내용은 ASP.NET Core에서 여러 환경 사용을 참조하세요.

appsettings.{Environment}.json 값은 appsettings.json의 키를 재정의합니다. 예를 들어 기본적으로 다음과 같습니다.

  • 개발 환경에서는 appsettings.Development.json 구성이 appsettings.json에서 찾은 값을 덮어씁니다.
  • 프로덕션 환경에서는 appsettings.Production.json 구성이 appsettings.json에서 찾은 값을 덮어씁니다. Azure에 앱을 배포하는 경우를 예로 들 수 있습니다.

구성 값을 보장해야 하는 경우 GetValue를 참조 하십시오. 위의 예제에서는 문자열만 읽고 기본값을 지원하지 않습니다.

기본 구성을 사용하여 appsettings.jsonappsettings.{Environment}.json 파일은 reloadOnChange: true를 통해 사용하도록 설정됩니다. 앱이 시작된 appsettings.jsonappsettings.{Environment}.json 파일에 대한 변경 내용은 JSON 구성 공급자에서 읽습니다.

옵션 패턴을 사용하여 계층적 구성 데이터 바인딩

관련 구성 값을 읽는 기본 방법은 옵션 패턴를 사용하는 것입니다. 예를 들어 다음 구성 값을 읽으려면:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

다음 PositionOptions 클래스를 만듭니다.

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

옵션 클래스:

  • 매개 변수가 없는 public 생성자를 사용하는 비추상이어야 합니다.
  • 형식의 모든 공용 읽기-쓰기 속성이 바인딩됩니다.
  • 필드가 바인딩되지 않습니다. 위 코드에서 Position은 바운딩되지 않습니다. Position 필드를 사용하므로 클래스를 구성 공급자에 바인딩할 때 문자열 "Position"을 앱에서 하드 코딩하지 않아도 됩니다.

코드는 다음과 같습니다.

  • ConfigurationBinder.Bind를 호출하여 PositionOptions 클래스를 Position 섹션에 바인딩합니다.
  • Position 구성 데이터를 표시합니다.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

위 코드에서는 기본적으로 앱을 시작한 후의 JSON 구성 파일의 변경 사항을 읽습니다.

ConfigurationBinder.Get<T>는 지정된 형식을 바인딩하고 반환합니다. ConfigurationBinder.Get<T>ConfigurationBinder.Bind를 사용하는 것보다 편리할 수 있습니다. 다음 코드에서는 ConfigurationBinder.Get<T>PositionOptions 클래스를 함께 사용하는 방법을 보여 줍니다.

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

위 코드에서는 기본적으로 앱을 시작한 후의 JSON 구성 파일의 변경 사항을 읽습니다.

옵션 패턴을 사용하는 경우 한 가지 대체 방법은 Position 섹션을 바인딩하고 종속성 주입 서비스 컨테이너에 추가하는 것입니다. 다음 코드에서 PositionOptionsConfigure를 통해 서비스 컨테이너에 추가되고 구성에 바인딩됩니다.

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

위의 코드를 사용하여 다음 코드는 위치 옵션을 읽습니다.

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

위 코드에서는 앱을 시작한 후의 JSON 구성 파일의 변경 사항은 읽지 않습니다. 앱을 시작한 후의 변경 사항을 읽으려면 IOptionsSnapshot을 사용합니다.

기본 구성을 사용하여 appsettings.jsonappsettings.{Environment}.json 파일은 reloadOnChange: true를 통해 사용하도록 설정됩니다. 앱이 시작된 appsettings.jsonappsettings.{Environment}.json 파일에 대한 변경 내용은 JSON 구성 공급자에서 읽습니다.

추가 JSON 구성 파일 추가에 대한 자세한 내용은 이 문서의 JSON 구성 공급자를 참조하세요.

서비스 컬렉션 결합

서비스를 등록하고 옵션을 구성하는 다음 메서드를 고려합니다.

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

관련 등록 그룹을 확장 메서드로 이동하여 서비스를 등록할 수 있습니다. 예를 들어, 구성 서비스는 다음 클래스에 추가됩니다.

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

나머지 서비스는 유사한 클래스에 등록됩니다. 다음 코드는 새 확장 메서드를 사용하여 서비스를 등록합니다.

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

참고:services.Add{GROUP_NAME} 확장 메서드는 서비스를 추가하고 잠재적으로 구성합니다. 예를 들어 AddControllersWithViews는 보기에 필요한 서비스 MVC 컨트롤러를 추가하고 AddRazorPages는 Razor Pages에 필요한 서비스를 추가합니다.

보안 및 사용자 비밀

구성 데이터 지침:

  • 구성 공급자 코드 또는 일반 텍스트 구성 파일에 암호 또는 기타 중요한 데이터를 절대 저장하지 마세요. 비밀 관리자 도구를 사용하여 개발에 사용되는 비밀을 저장할 수 있습니다.
  • 개발 또는 테스트 환경에서 프로덕션 비밀을 사용하지 마세요.
  • 의도치 않게 소스 코드 리포지토리에 커밋되는 일이 없도록 프로젝트 외부에서 비밀을 지정하세요.

기본적으로, 사용자 비밀 구성 원본은 JSON 구성 원본 뒤에 등록됩니다. 따라서 사용자 비밀 키가 appsettings.jsonappsettings.{Environment}.json의 키보다 우선합니다.

암호 또는 기타 중요한 데이터 저장에 대한 자세한 정보:

Azure Key Vault가 ASP.NET Core 앱에 대한 앱 비밀을 안전하게 저장합니다. 자세한 내용은 ASP.NET Core의 Azure Key Vault 구성 공급자를 참조하세요.

접두사가 없는 환경 변수

접두사가 없는 환경 변수는 ASPNETCORE_ 또는 DOTNET_ 접두사가 붙은 변수가 아니라 환경 변수입니다. 예를 들어, ASP.NET Core 웹 애플리케이션 템플릿은 launchSettings.json에서 "ASPNETCORE_ENVIRONMENT": "Development"을 설정합니다. ASPNETCORE_DOTNET_ 환경 변수에 대한 자세한 내용은 다음을 참조하세요.

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

: 구분 기호는 모든 플랫폼의 환경 변수 계층적 키에서 작동하지 않습니다. 이중 밑줄 __은 다음과 같습니다.

  • 모든 플랫폼에서 지원됩니다. 예를 들어 : 구분 기호는 Bash에서 지원되지 않지만 __은 지원됩니다.
  • 자동으로 :으로 대체

다음 set 명령은,

  • Windows에서 위의 예제에 나오는 환경 키 및 값을 설정합니다.
  • 샘플 다운로드를 사용하는 경우 설정을 테스트합니다. dotnet run 명령은 프로젝트 디렉터리에서 실행해야 합니다.
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

위의 환경 설정은,

  • 설정된 명령 창에서 시작된 프로세스에서만 설정됩니다.
  • Visual Studio에서 시작된 브라우저에서는 읽을 수 없습니다.

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

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

위의 명령이 appsettings.jsonappsettings.{Environment}.json을 재정의하는지 테스트하려면:

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

환경 변수의 접두사를 지정하는 문자열을 사용하여 AddEnvironmentVariables를 호출합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

var app = builder.Build();

위의 코드에서

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

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

다음 명령은 사용자 지정 접두사를 테스트합니다.

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

기본 구성DOTNET_ASPNETCORE_ 접두사가 붙은 환경 변수 및 명령줄 인수를 로드합니다. DOTNET_ASPNETCORE_ 접두사는 ASP.NET Core에서 호스트 및 앱 구성에 사용되지만, 사용자 구성에는 사용되지 않습니다. 호스트 및 앱 구성에 대한 자세한 내용은 .NET 제네릭 호스트를 참조하세요.

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

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

자세한 내용은 Azure 앱: Azure Portal을 사용하여 앱 구성 재정의를 참조하세요.

Azure 데이터베이스 연결 문자열에 대한 자세한 내용은 연결 문자열 접두사를 참조하세요.

환경 변수 명명

환경 변수의 이름은 appsettings.json 파일의 구조를 반영합니다. 계층 구조의 각 요소는 이중 밑줄(권장) 또는 콜론으로 구분됩니다. 요소 구조에 배열이 포함된 경우, 해당 배열 인덱스는 이 경로의 추가 요소 이름으로 처리되어야 합니다. 다음 appsettings.json 파일 및 환경 변수라고 표시된 해당 값을 살펴보세요.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

환경 변수

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

생성된 launchSettings.json에 설정된 환경 변수

설정된 launchSettings.json 환경 변수는 시스템 환경에서 설정된 변수를 재정의합니다. 예를 들어 ASP.NET Core 웹 템플릿은 엔드포인트 구성을 다음으로 launchSettings.json 설정하는 파일을 생성합니다.

"applicationUrl": "https://localhost:5001;http://localhost:5000"

applicationUrl 구성은 ASPNETCORE_URLS 환경 변수를 설정하고 환경에 설정된 값을 재정의합니다.

Linux에서 환경 변수 이스케이프

Linux에서는 URL 환경 변수의 값을 이스케이프 처리하여 systemd가 구문 분석을 할 수 있도록 해야 합니다. http:--localhost:5001을 생성하는 Linux 도구 systemd-escape를 사용하세요.

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

환경 변수 표시

다음 코드는 애플리케이션 시작 시 환경 설정을 디버그할 때 도움이 될 수 있는 환경 변수 및 값을 표시합니다.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

명령줄

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

  • appsettings.jsonappsettings.{Environment}.json 파일입니다.
  • 개발 환경의 앱 비밀.
  • 환경 변수입니다.

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

명령줄 인수

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

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

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

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

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

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

키 값은,

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

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

스위치 매핑

스위치 매핑은 이름 교체 논리를 지원합니다. AddCommandLine 메서드에 스위치 교체 사전을 제공합니다.

스위치 매핑 사전을 사용하면 명령줄 인수를 통해 제공된 키와 일치하는 키에 대해 사전을 검사합니다. 사전에서 명령줄 키가 발견되면 사전 값이 다시 전달되어 앱 구성의 키-값 쌍이 설정됩니다. 단일 대시(-) 접두사가 붙은 명령줄 키에는 스위치 매핑이 필수입니다.

스위치 매핑 사전 키 규칙:

  • 스위치는 - 또는 --으로 시작해야 합니다.
  • 스위치 매핑 사전이 중복 키를 포함하면 안 됩니다.

스위치 매핑 사전을 사용하려면 AddCommandLine에 대한 호출에 전달합니다.


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

다음 명령을 실행하여 키 교체를 테스트합니다.

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

다음 코드는 교체된 키의 키 값을 보여 줍니다.

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

스위치 매핑을 사용하는 앱의 경우 CreateDefaultBuilder에 대한 호출은 인수를 전달하지 않아야 합니다. CreateDefaultBuilder 메서드의 AddCommandLine 호출에는 매핑된 스위치가 포함되지 않으며 CreateDefaultBuilder에 스위치 매핑 사전을 전달할 방법은 없습니다. 해결 방법으로 CreateDefaultBuilder에 인수를 전달하지 않고 대신 ConfigurationBuilder 메서드의 AddCommandLine 메서드에서 인수와 스위치 매핑 사전을 모두 처리하도록 할 수 있습니다.

Visual Studio에서 환경 및 명령줄 인수 설정

Visual Studio의 시작 프로필 대화 상자에서 환경 및 명령줄 인수를 설정할 수 있습니다.

  • 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.
  • 디버그 > 일반 탭을 선택하고 디버그 시작 프로필 UI 열기를 선택합니다.

계층적 구성 데이터

구성 API는 구성 키에 구분 기호를 사용해 계층적 데이터를 평면화하여 계층적 구성 데이터를 읽습니다.

샘플 다운로드에는 다음 appsettings.json 파일이 포함되어 있습니다.

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

샘플 다운로드의 다음 코드는 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

계층적 구성 데이터를 읽는 기본 방법은 옵션 패턴을 사용하는 것입니다. 자세한 내용은 이 문서의 계층적 구성 데이터 바인딩을 참조하세요.

구성 데이터에서는 GetSectionGetChildren 메서드를 사용하여 섹션과 섹션의 자식을 격리할 수 있습니다. 이러한 메서드에 대해서는 나중에 GetSection, GetChildren 및 Exists에서 설명합니다.

구성 키 및 값

구성 키는,

  • 대/소문자를 구분하지 않습니다. 예를 들어 ConnectionStringconnectionstring은 동일한 키로 처리됩니다.
  • 두 개 이상의 구성 공급자에 키와 값이 설정되어 있으면 추가된 마지막 공급자의 값이 사용됩니다. 자세한 내용은 기본 구성을 참조하세요.
  • 계층적 키
    • 구성 API 내에서는 콜론 구분 기호(:)가 모든 플랫폼에 적용됩니다.
    • 환경 변수에서는 콜론 구분 기호가 일부 플랫폼에 적용되지 않을 수 있습니다. 두 개의 밑줄(__)은 모든 플랫폼에서 지원되며 콜론(:)으로 자동 변환됩니다.
    • Azure Key Vault에서 계층적 키는 --를 구분 기호로 사용합니다. Azure Key Vault 구성 공급자는 암호를 앱의 구성으로 로드할 때 --를 자동으로 :으로 바꿉니다.
  • ConfigurationBinder는 구성 키에 배열 인덱스를 사용하여 배열을 개체에 바인딩하는 것을 지원합니다. 배열 바인딩에 대해서는 클래스에 배열 바인딩 섹션에서 설명합니다.

구성 값은,

  • 문자열입니다.
  • Null 값은 구성에 저장하거나 개체에 바인딩할 수 없습니다.

구성 공급자

다음 표에서는 ASP.NET Core 앱에서 사용할 수 있는 구성 공급자를 보여 줍니다.

공급자 다음에서 구성 제공
Azure Key Vault 구성 공급자 Azure Key Vault
Azure 앱 구성 공급자 Azure App Configuration
명령줄 구성 공급자 명령줄 매개 변수
사용자 지정 구성 공급자 사용자 지정 소스
환경 변수 구성 공급자 환경 변수
파일 구성 공급자 INI, JSON 및 XML 파일
파일별 키 구성 공급자 디렉터리 파일
메모리 구성 공급자 메모리 내 컬렉션
사용자 비밀 사용자 프로필 디렉터리의 파일

구성 공급자에서 지정한 순서로 구성 소스를 읽습니다. 앱에 필요한 기본 구성 소스에 대한 우선 순위에 맞게 구성 공급자를 코드에 정렬하세요.

구성 공급자의 일반적인 순서는 다음과 같습니다.

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. 사용자 비밀
  4. 환경 변수 구성 공급자를 사용하는 환경 변수
  5. 명령줄 구성 공급자를 사용하는 명령줄 인수

일반적인 방식은 명령줄 구성 공급자를 일련의 공급자에서 마지막에 추가하는 것이므로, 다른 공급자에서 설정한 구성을 명령줄 인수로 재정의할 수 있습니다.

위의 공급자 시퀀스는 기본 구성에서 사용됩니다.

연결 문자열 접두사

구성 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

파일 구성 공급자

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

INI 구성 공급자

IniConfigurationProvider는 런타임에 INI 파일 키-값 쌍에서 구성을 로드합니다.

다음 코드는 여러 구성 공급자를 추가합니다.

var builder = WebApplication.CreateBuilder(args);

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

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

위의 코드에서 MyIniConfig.iniMyIniConfig.{Environment}.ini 파일의 설정은 다음의 설정에 의해 재정의됩니다.

샘플 다운로드에는 다음 MyIniConfig.ini 파일이 포함되어 있습니다.

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

JSON 구성 공급자

JsonConfigurationProvider은(는) JSON 파일 키-값 쌍에서 구성을 로드합니다.

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

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

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

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

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

일반적으로 사용자 지정 JSON 파일은 환경 변수 구성 공급자명령줄 구성 공급자에 설정된 값을 재정의하지 않습니다.

XML 구성 공급자

XmlConfigurationProvider는 런타임에 XML 파일 키-값 쌍에서 구성을 로드합니다.

다음 코드는 여러 구성 공급자를 추가합니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

위의 코드에서 MyXMLFile.xmlMyXMLFile.{Environment}.xml 파일의 설정은 다음의 설정에 의해 재정의됩니다.

샘플 다운로드에는 다음 MyXMLFile.xml 파일이 포함되어 있습니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

샘플 다운로드의 다음 코드는 위의 몇 가지 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

같은 요소 이름을 사용하는 반복 요소는 다음과 같이 name 특성을 사용하여 요소를 구분하면 작동합니다.

<?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>

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

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

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

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

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

  • key:attribute
  • section:key:attribute

파일별 키 구성 공급자

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

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

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

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

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

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

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

메모리 구성 공급자

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

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

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

샘플 다운로드의 다음 코드는 위의 구성 설정을 표시합니다.

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

위의 코드에서 config.AddInMemoryCollection(Dict)기본 구성 공급자 뒤에 추가됩니다. 구성 공급자 순서 지정 예제는 JSON 구성 공급자를 참조하세요.

MemoryConfigurationProvider를 사용하는 또 다른 예제는 배열 바인딩을 참조하세요.

Kestrel 엔드포인트 구성

Kestrel 관련 엔드포인트 구성은 모든 서버 간 엔드포인트 구성을 재정의합니다. 서버 간 엔드포인트 구성에는 다음이 포함됩니다.

ASP.NET Core 웹 앱에서 사용되는 다음 appsettings.json 파일을 고려합니다.

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

위에 강조 표시된 마크업을 ASP.NET Core 웹앱에 사용하면서 다음과 같은 서버 간 엔드포인트 구성을 사용하여 명령줄에서 앱을 시작하는 경우,

dotnet run --urls="https://localhost:7777"

Kestrel은 https://localhost:7777이 아닌 appsettings.json 파일(https://localhost:9999)에서 Kestrel용으로 특별히 구성된 엔드포인트에 바인딩합니다.

환경 변수로 구성된 Kestrel 관련 엔드포인트를 고려합니다.

set Kestrel__Endpoints__Https__Url=https://localhost:8888

위 환경 변수에서 Https는 Kestrel 관련 엔드포인트의 이름입니다. 또한 위 appsettings.json 파일은 Https라는 Kestrel 관련 엔드포인트를 정의합니다. 기본적으로환경 변수 구성 공급자를 사용하는 환경 변수는 appsettings.{Environment}.json 이후에 읽혀지므로 위 환경 변수는 Https 엔드포인트에 사용됩니다.

GetValue

ConfigurationBinder.GetValue는 지정된 키를 사용하여 구성에서 단일 값을 추출하고 해당 값을 지정된 형식으로 변환합니다.

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

위의 코드에서 구성에 NumberKey가 없는 경우 기본값 99가 사용됩니다.

GetSection, GetChildren 및 Exists

이어지는 예제에서는 다음 MySubsection.json 파일을 고려하세요.

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

다음 코드는 구성 공급자에 추가 MySubsection.json 됩니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection 는 지정된 하위 섹션 키가 있는 구성 하위 섹션을 반환합니다.

다음 코드는 section1의 값을 반환합니다.

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

다음 코드는 section2:subsection0의 값을 반환합니다.

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSectionnull을 반환하지 않습니다. 일치하는 섹션을 찾을 수 없으면 빈 IConfigurationSection이 반환됩니다.

GetSection이 일치하는 섹션을 반환할 때 Value는 채워지지 않습니다. 섹션이 존재하면 KeyPath가 반환됩니다.

GetChildren 및 Exists

다음 코드는 다음에 대한 section2:subsection0값을 호출 IConfiguration.GetChildren 하고 반환합니다.

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

이전 코드는 섹션이 있는지 확인하기 위해 호출 ConfigurationExtensions.Exists 합니다.

배열 바인딩

ConfigurationBinder.Bind는 구성 키에 배열 인덱스를 사용하여 배열을 개체에 바인딩하는 것을 지원합니다. 숫자 키 세그먼트를 노출하는 모든 배열 형식은 POCO 클래스 배열에 배열을 바인딩할 수 있습니다.

샘플 다운로드고려합니다MyArray.json.

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

다음 코드는 구성 공급자에 추가 MyArray.json 됩니다.

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

다음 코드는 구성을 읽고 값을 표시합니다.

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

위의 코드는 다음 출력을 반환합니다.

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

위의 출력에서 Index 3은 MyArray.json"4": "value40",에 해당하는 value40 값을 가집니다. 바인딩된 배열 인덱스는 연속되며 구성 키 인덱스에 바인딩되지 않습니다. 구성 바인더는 null 값을 바인딩하거나 바인딩된 개체에 null 항목을 만들 수 없습니다.

사용자 지정 구성 공급자

샘플 앱에서는 EF(Entity Framework)를 사용하여 데이터베이스에서 구성 키-값 쌍을 읽는 기본 구성 공급자를 만드는 방법을 보여 줍니다.

이 공급자의 특징은 다음과 같습니다.

  • 데모용으로 EF 메모리 내 데이터베이스를 사용합니다. 연결 문자열이 필요한 데이터베이스를 사용하려면 보조 ConfigurationBuilder를 구현하여 다른 구성 공급자에서 연결 문자열을 제공하세요.
  • 이 공급자는 시작 시 데이터베이스 테이블을 구성으로 읽어 들입니다. 이 공급자는 키별 기준으로 데이터베이스를 쿼리하지 않습니다.
  • 변경 시 다시 로드가 구현되지 않으므로 앱 시작 후 데이터베이스를 업데이트해도 앱 구성에 영향을 주지 않습니다.

데이터베이스에 구성 값을 저장하는 EFConfigurationValue 엔터티를 정의합니다.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

구성된 값을 저장 및 액세스하는 EFConfigurationContext를 추가합니다.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

IConfigurationSource를 구현하는 클래스를 만듭니다.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

ConfigurationProvider에서 상속하여 사용자 지정 구성 공급자를 만듭니다. 구성 공급자는 비어 있는 데이터베이스를 초기화합니다. 구성 키는 대/소문자를 구분하지 않으므로 데이터베이스를 초기화하는 데 사용되는 사전은 대/소문자를 구분하지 않는 비교자(StringComparer.OrdinalIgnoreCase)를 사용하여 생성됩니다.

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

AddEFConfiguration 확장 메서드를 사용하여 구성 소스를 ConfigurationBuilder에 추가할 수 있습니다.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

다음 코드는 다음에서 사용자 지정 EFConfigurationProvider 을 사용하는 방법을 보여줍니다.Program.cs

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

DI(종속성 주입)를 통해 구성에 액세스

IConfiguration 서비스를 확인하여 DI(종속성 주입)를 사용하여 구성을 서비스에 주입할 수 있습니다.

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

IConfiguration을 사용하여 값에 액세스하는 방법에 대한 내용은 이 문서의 GetValueGetSection, GetChildren 및 Exists를 참조하세요.

Razor Pages의 구성 액세스

다음 코드는 Razor 페이지의 구성 데이터를 표시합니다.

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

다음 코드에서 MyOptionsConfigure를 통해 서비스 컨테이너에 추가되고 구성에 바인딩됩니다.

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

다음 태그는 지시문을 @injectRazor 사용하여 옵션 값을 확인하고 표시합니다.

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

MVC 뷰 파일의 구성 액세스

다음 코드는 MVC 뷰의 구성 데이터를 표시합니다.

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Program.cs의 구성 액세스

다음 코드는 Program.cs 파일의 구성에 액세스합니다.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

appsettings.json 앞의 예제에서는 다음을 수행합니다.

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

대리자로 옵션 구성

대리자에서 구성된 옵션은 구성 공급자에 설정된 값을 재정의합니다.

다음 코드에서 IConfigureOptions<TOptions> 서비스가 서비스 컨테이너에 추가됩니다. MyOptions의 값을 구성하는 데 대리자를 사용합니다.

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

다음 코드는 다음과 같은 옵션 값을 표시합니다.

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

위의 예제에서 Option1Option2의 값은 모두 appsettings.json에서 지정되고 구성된 대리자에 의해 재정의됩니다.

호스트 대 앱 구성

앱을 구성하고 시작하기 전에 호스트를 구성하고 시작합니다. 호스트는 앱 시작 및 수명 관리를 담당합니다. 앱과 호스트 모두 이 항목에서 설명하는 구성 관리자를 사용하여 구성합니다. 호스트 구성 키-값 쌍은 앱의 구성에도 포함됩니다. 호스트를 빌드할 때 구성 공급자를 사용하는 방법과 구성 소스가 호스트 구성에 미치는 영향에 대한 자세한 내용은 ASP.NET Core 기본 사항 개요를 참조하세요.

기본 호스트 구성

웹 호스트를 사용하는 경우 기본 구성에 대한 자세한 내용은 이 항목의 ASP.NET Core 2.2 버전을 참조하세요.

  • 호스트 구성은 다음에서 제공됩니다.
  • 웹 호스트 기본 구성이 설정됨(ConfigureWebHostDefaults):
    • Kestrel은 웹 서버로 사용되며 앱의 구성 공급자를 사용하여 구성됩니다.
    • 호스트 필터링 미들웨어를 추가합니다.
    • ASPNETCORE_FORWARDEDHEADERS_ENABLED 환경 변수가 true로 설정된 경우 전달된 헤더 미들웨어를 추가합니다.
    • IIS 통합을 사용하도록 설정합니다.

기타 구성

이 항목에서는 앱 구성에 관련된 내용만 다룹니다. ASP.NET Core 앱을 실행하고 호스팅하는 다른 요소는 이 항목에서 다루지 않는 구성 파일을 사용하여 구성됩니다.

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

이전 버전의 ASP.NET 앱 구성을 마이그레이션하는 방법에 대한 자세한 내용은 ASP.NET ASP.NET Core로 업데이트를 참조 하세요.

외부 어셈블리의 구성 추가

IHostingStartup 구현은 시작 시 앱의 Startup 클래스 외부에 있는 외부 어셈블리에서 앱에 향상된 기능을 추가할 수 있습니다. 자세한 내용은 ASP.NET Core에서 호스팅 시작 어셈블리 사용을 참조하세요.

추가 리소스

Kestrel 엔드포인트 구성

Kestrel 관련 엔드포인트 구성은 모든 서버 간 엔드포인트 구성을 재정의합니다. 서버 간 엔드포인트 구성에는 다음이 포함됩니다.

ASP.NET Core 웹 앱에서 사용되는 다음 appsettings.json 파일을 고려합니다.

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

위에 강조 표시된 마크업을 ASP.NET Core 웹앱에 사용하면서 다음과 같은 서버 간 엔드포인트 구성을 사용하여 명령줄에서 앱을 시작하는 경우,

dotnet run --urls="https://localhost:7777"

Kestrel은 https://localhost:7777이 아닌 appsettings.json 파일(https://localhost:9999)에서 Kestrel용으로 특별히 구성된 엔드포인트에 바인딩합니다.

환경 변수로 구성된 Kestrel 관련 엔드포인트를 고려합니다.

set Kestrel__Endpoints__Https__Url=https://localhost:8888

위 환경 변수에서 Https는 Kestrel 관련 엔드포인트의 이름입니다. 또한 위 appsettings.json 파일은 Https라는 Kestrel 관련 엔드포인트를 정의합니다. 기본적으로환경 변수 구성 공급자를 사용하는 환경 변수는 appsettings.{Environment}.json 이후에 읽혀지므로 위 환경 변수는 Https 엔드포인트에 사용됩니다.

GetValue

ConfigurationBinder.GetValue는 지정된 키를 사용하여 구성에서 단일 값을 추출하고 해당 값을 지정된 형식으로 변환합니다. 이 메서드는 IConfiguration의 확장 메서드입니다.

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

위의 코드에서 구성에 NumberKey가 없는 경우 기본값 99가 사용됩니다.

GetSection, GetChildren 및 Exists

이어지는 예제에서는 다음 MySubsection.json 파일을 고려하세요.

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

다음 코드는 구성 공급자에 추가 MySubsection.json 됩니다.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MySubsection.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

GetSection

IConfiguration.GetSection 는 지정된 하위 섹션 키가 있는 구성 하위 섹션을 반환합니다.

다음 코드는 section1의 값을 반환합니다.

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

다음 코드는 section2:subsection0의 값을 반환합니다.

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSectionnull을 반환하지 않습니다. 일치하는 섹션을 찾을 수 없으면 빈 IConfigurationSection이 반환됩니다.

GetSection이 일치하는 섹션을 반환할 때 Value는 채워지지 않습니다. 섹션이 존재하면 KeyPath가 반환됩니다.

GetChildren 및 Exists

다음 코드는 다음에 대한 section2:subsection0값을 호출 IConfiguration.GetChildren 하고 반환합니다.

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = null;
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new System.Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

이전 코드는 섹션이 있는지 확인하기 위해 호출 ConfigurationExtensions.Exists 합니다.

배열 바인딩

ConfigurationBinder.Bind는 구성 키에 배열 인덱스를 사용하여 배열을 개체에 바인딩하는 것을 지원합니다. 숫자 키 세그먼트를 노출하는 모든 배열 형식은 POCO 클래스 배열에 배열을 바인딩할 수 있습니다.

샘플 다운로드고려합니다MyArray.json.

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

다음 코드는 구성 공급자에 추가 MyArray.json 됩니다.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MyArray.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

다음 코드는 구성을 읽고 값을 표시합니다.

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

위의 코드는 다음 출력을 반환합니다.

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

위의 출력에서 Index 3은 MyArray.json"4": "value40",에 해당하는 value40 값을 가집니다. 바인딩된 배열 인덱스는 연속되며 구성 키 인덱스에 바인딩되지 않습니다. 구성 바인더는 null 값을 바인딩하거나 바인딩된 개체에 null 항목을 만들 수 없습니다.

다음 코드는 AddInMemoryCollection 확장 메서드를 사용하여 array:entries 구성을 로드합니다.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

다음 코드는 arrayDictDictionary의 구성을 읽고 값을 표시합니다.

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

위의 코드는 다음 출력을 반환합니다.

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value4
Index: 4  Value: value5

바인딩된 개체의 index #3은 array:4 구성 키에 대한 구성 데이터와 value4의 값을 포함합니다. 배열이 포함된 구성 데이터를 바인딩할 때 구성 키의 배열 인덱스는 개체를 만들 때 구성 데이터를 반복하는 데 사용됩니다. 구성 데이터에 null 값을 유지할 수 없으며, 구성 키의 배열에서 하나 이상의 인덱스를 건너뛰더라도 바인딩된 개체에 null 값 항목이 생성되지 않습니다.

index #3에 대한 누락된 구성 항목은 index #3 키/값 쌍을 읽는 모든 구성 공급자에서 ArrayExample 인스턴스에 바인딩하기 전에 제공할 수 있습니다. 샘플 다운로드에서 다음 Value3.json 파일을 고려합니다.

{
  "array:entries:3": "value3"
}

다음 코드에는 Value3.jsonarrayDictDictionary의 구성이 포함되어 있습니다.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile("Value3.json",
                                    optional: false, reloadOnChange: false);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

다음 코드는 위의 구성을 읽고 값을 표시합니다.

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

위의 코드는 다음 출력을 반환합니다.

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value3
Index: 4  Value: value4
Index: 5  Value: value5

배열 바인딩을 구현하기 위해 사용자 지정 구성 공급자가 필요하지는 않습니다.

사용자 지정 구성 공급자

샘플 앱에서는 EF(Entity Framework)를 사용하여 데이터베이스에서 구성 키-값 쌍을 읽는 기본 구성 공급자를 만드는 방법을 보여 줍니다.

이 공급자의 특징은 다음과 같습니다.

  • 데모용으로 EF 메모리 내 데이터베이스를 사용합니다. 연결 문자열이 필요한 데이터베이스를 사용하려면 보조 ConfigurationBuilder를 구현하여 다른 구성 공급자에서 연결 문자열을 제공하세요.
  • 이 공급자는 시작 시 데이터베이스 테이블을 구성으로 읽어 들입니다. 이 공급자는 키별 기준으로 데이터베이스를 쿼리하지 않습니다.
  • 변경 시 다시 로드가 구현되지 않으므로 앱 시작 후 데이터베이스를 업데이트해도 앱 구성에 영향을 주지 않습니다.

데이터베이스에 구성 값을 저장하는 EFConfigurationValue 엔터티를 정의합니다.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; }
    public string Value { get; set; }
}

구성된 값을 저장 및 액세스하는 EFConfigurationContext를 추가합니다.

EFConfigurationProvider/EFConfigurationContext.cs:

// using Microsoft.EntityFrameworkCore;

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values { get; set; }
}

IConfigurationSource를 구현하는 클래스를 만듭니다.

EFConfigurationProvider/EFConfigurationSource.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
    {
        _optionsAction = optionsAction;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

ConfigurationProvider에서 상속하여 사용자 지정 구성 공급자를 만듭니다. 구성 공급자는 비어 있는 데이터베이스를 초기화합니다. 구성 키는 대/소문자를 구분하지 않으므로 데이터베이스를 초기화하는 데 사용되는 사전은 대/소문자를 구분하지 않는 비교자(StringComparer.OrdinalIgnoreCase)를 사용하여 생성됩니다.

EFConfigurationProvider/EFConfigurationProvider.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues = 
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "quote1", "I aim to misbehave." },
                { "quote2", "I swallowed a bug." },
                { "quote3", "You can't stop the signal, Mal." }
            };

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue 
                {
                    Id = kvp.Key,
                    Value = kvp.Value
                })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

AddEFConfiguration 확장 메서드를 사용하여 구성 소스를 ConfigurationBuilder에 추가할 수 있습니다.

Extensions/EntityFrameworkExtensions.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
        this IConfigurationBuilder builder, 
        Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

다음 코드는 다음에서 사용자 지정 EFConfigurationProvider 을 사용하는 방법을 보여줍니다.Program.cs

// using Microsoft.EntityFrameworkCore;

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddEFConfiguration(
                options => options.UseInMemoryDatabase("InMemoryDb"));
        })

시작 시 구성 액세스

다음 코드는 Startup 메서드의 구성 데이터를 표시합니다.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        Console.WriteLine($"MyKey : {Configuration["MyKey"]}");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        Console.WriteLine($"Position:Title : {Configuration["Position:Title"]}");

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

시작 편의 메서드를 사용하여 구성에 액세스하는 방법의 예는 앱 시작: 편의 메서드를 참조하세요.

Razor Pages의 구성 액세스

다음 코드는 Razor 페이지의 구성 데이터를 표시합니다.

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

다음 코드에서 MyOptionsConfigure를 통해 서비스 컨테이너에 추가되고 구성에 바인딩됩니다.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));

    services.AddRazorPages();
}

다음 태그는 지시문을 @injectRazor 사용하여 옵션 값을 확인하고 표시합니다.

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

MVC 뷰 파일의 구성 액세스

다음 코드는 MVC 뷰의 구성 데이터를 표시합니다.

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

대리자로 옵션 구성

대리자에서 구성된 옵션은 구성 공급자에 설정된 값을 재정의합니다.

대리자를 사용한 옵션 구성은 샘플 앱에 예제 2로 설명되어 있습니다.

다음 코드에서 IConfigureOptions<TOptions> 서비스가 서비스 컨테이너에 추가됩니다. MyOptions의 값을 구성하는 데 대리자를 사용합니다.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(myOptions =>
    {
        myOptions.Option1 = "Value configured in delegate";
        myOptions.Option2 = 500;
    });

    services.AddRazorPages();
}

다음 코드는 다음과 같은 옵션 값을 표시합니다.

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

위의 예제에서 Option1Option2의 값은 모두 appsettings.json에서 지정되고 구성된 대리자에 의해 재정의됩니다.

호스트 대 앱 구성

앱을 구성하고 시작하기 전에 호스트를 구성하고 시작합니다. 호스트는 앱 시작 및 수명 관리를 담당합니다. 앱과 호스트 모두 이 항목에서 설명하는 구성 관리자를 사용하여 구성합니다. 호스트 구성 키-값 쌍은 앱의 구성에도 포함됩니다. 호스트를 빌드할 때 구성 공급자를 사용하는 방법과 구성 소스가 호스트 구성에 미치는 영향에 대한 자세한 내용은 ASP.NET Core 기본 사항 개요를 참조하세요.

기본 호스트 구성

웹 호스트를 사용하는 경우 기본 구성에 대한 자세한 내용은 이 항목의 ASP.NET Core 2.2 버전을 참조하세요.

  • 호스트 구성은 다음에서 제공됩니다.
    • 환경 변수 구성 공급자를 사용하는 DOTNET_ 접두사가 붙은 환경 변수(예: DOTNET_ENVIRONMENT). 구성 키-값 쌍이 로드되면 접두사(DOTNET_)는 제거됩니다.
    • 명령줄 구성 공급자를 사용하는 명령줄 인수
  • 웹 호스트 기본 구성이 설정됨(ConfigureWebHostDefaults):
    • Kestrel은 웹 서버로 사용되며 앱의 구성 공급자를 사용하여 구성됩니다.
    • 호스트 필터링 미들웨어를 추가합니다.
    • ASPNETCORE_FORWARDEDHEADERS_ENABLED 환경 변수가 true로 설정된 경우 전달된 헤더 미들웨어를 추가합니다.
    • IIS 통합을 사용하도록 설정합니다.

기타 구성

이 항목에서는 앱 구성에 관련된 내용만 다룹니다. ASP.NET Core 앱을 실행하고 호스팅하는 다른 요소는 이 항목에서 다루지 않는 구성 파일을 사용하여 구성됩니다.

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

이전 버전의 ASP.NET 앱 구성을 마이그레이션하는 방법에 대한 자세한 내용은 ASP.NET ASP.NET Core로 업데이트를 참조 하세요.

외부 어셈블리의 구성 추가

IHostingStartup 구현은 시작 시 앱의 Startup 클래스 외부에 있는 외부 어셈블리에서 앱에 향상된 기능을 추가할 수 있습니다. 자세한 내용은 ASP.NET Core에서 호스팅 시작 어셈블리 사용을 참조하세요.

추가 리소스