.NET の構成プロバイダー

.NET の構成は、構成プロバイダーで行うことができます。 いくつかの種類のプロバイダーは、さまざまな構成ソースに依存します。 この記事では、さまざまな構成プロバイダーとそれに対応するソースについて詳しく説明します。

ファイル構成プロバイダー

FileConfigurationProvider は、ファイル システムから構成を読み込むための基本クラスです。 以下の構成プロバイダーは FileConfigurationProvider から派生したものです:

キーでは、大文字と小文字は区別されません。 すべてのファイル構成プロバイダーは、1 つのプロバイダーで重複するキーが見つかったときに FormatException をスローします。

JSON 構成プロバイダー

JsonConfigurationProvider クラスにより、構成が JSON ファイルから読み込まれます。 Microsoft.Extensions.Configuration.Json NuGet パッケージをインストールします。

オーバーロードでは、次の指定ができます:

  • ファイルを省略可能かどうか。
  • ファイルが変更された場合に構成を再度読み込むかどうか。

次のコードがあるとします。

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

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

IHostEnvironment env = builder.Environment;

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

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

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

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

上記のコードでは次の操作が行われます。

  • CreateApplicationBuilder(String[]) メソッドにおいて既定で追加されたすべての既存の構成プロバイダーをクリアします。
  • 次のオプションを使用して appsettings.json ファイルと appsettings.Environment.json ファイルを読み込むように、JSON 構成プロバイダーを構成します。
    • optional: true:ファイルは省略可能です。
    • reloadOnChange: true: 変更が保存されると、ファイルが再読み込みされます。

重要

IConfigurationBuilder.Add構成プロバイダーを追加するとき、追加された構成プロバイダーは、IConfigurationSource リストの最後に追加されます。 複数のプロバイダーがキーを見つけた場合、キーを読み込んだ最後のプロバイダーによって前のプロバイダーがオーバーライドされます。

さまざまな構成設定の appsettings.json ファイルの例を次に示します。

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

IConfigurationBuilder インスタンスから、構成プロバイダーを追加した後、IConfigurationBuilder.Build() を呼び出して IConfigurationRoot オブジェクトを取得できます。 構成ルートは、構成階層のルートを表します。 構成のセクションを .NET オブジェクトのインスタンスにバインドし、後で依存関係の挿入により IOptions<TOptions> として提供されることができます。

Note

JSON ファイルの [ビルド アクション][出力ディレクトリにコピー] プロパティは、それぞれ [コンテンツ][新しい場合はコピーする] (または [常にコピーする]) に設定する必要があります。

次のように定義された TransientFaultHandlingOptions クラスについて考えてみましょう。

namespace ConsoleJson.Example;

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

次のコードにより、構成ルートが構築され、セクションが TransientFaultHandlingOptions クラスの型にバインドされて、バインドされた値がコンソール ウィンドウに出力されます。

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

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

アプリケーションによって、次のサンプル出力が書き込まれます。

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

XML 構成プロバイダー

XmlConfigurationProvider クラスにより、実行時に XML ファイルから構成が読み込まれます。 Microsoft.Extensions.Configuration.Xml NuGet パッケージをインストールします。

次のコードは、XML 構成プロバイダーを使用する XML ファイルの構成を示したものです。

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

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Configuration.Sources.Clear();

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

builder.Configuration.AddEnvironmentVariables();

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

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

上記のコードでは次の操作が行われます。

  • CreateApplicationBuilder(String[]) メソッドにおいて既定で追加されたすべての既存の構成プロバイダーをクリアします。
  • 次のオプションを使用して appsettings.xml および repeating-example.xml ファイルを読み込むように、XML 構成プロバイダーを構成します。
    • optional: true:ファイルは省略可能です。
    • reloadOnChange: true: 変更が保存されると、ファイルが再読み込みされます。
  • 環境変数構成プロバイダーを構成します。
  • 指定された args に引数が含まれる場合、コマンドライン構成プロバイダーを構成します。

XML の設定は、環境変数構成プロバイダーコマンドライン構成プロバイダーの設定によってオーバーライドされます。

さまざまな構成設定の appsettings.xml ファイルの例を次に示します。

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

ヒント

WinForms アプリで IConfiguration 型を使用するには、Microsoft.Extensions.Configuration.Xml NuGet パッケージへの参照を追加します。 ConfigurationBuilder のインスタンスを作成し、AddXmlFileBuild() の呼び出しをチェーンにします。 詳細については、「.NET Docs Issue #29679」を参照してください。

.NET 5 以前のバージョンでは、name 属性を追加することで、同じ要素名を使用する繰り返し要素を区別します。 .NET 6 以降のバージョンでは、XML 構成プロバイダーにより、繰り返し要素に自動的にインデックスが設定されます。 つまり、キーに "0" のインデックスが必要で、要素が 1 つだけの場合を除き、name 属性を指定する必要はありません。 (.NET 6 以降にアップグレードする場合は、この動作の変更によって中断が発生する可能性があります。詳細については、「繰り返し XML 要素にインデックスが含まれる」を参照してください。)

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

以下のコードでは、前の構成ファイルを読み取って、キーと値を表示します:

IConfigurationRoot configurationRoot = builder.Configuration;

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

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

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

アプリケーションにより、次のサンプル出力が書き込まれます。

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

値を指定するために属性を使用できます。

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

前の構成ファイルでは、value を使用して次のキーが読み込まれます。

  • key:attribute
  • section:key:attribute

INI 構成プロバイダー

IniConfigurationProvider クラスにより、実行時に INI ファイルから構成が読み込まれます。 Microsoft.Extensions.Configuration.Ini NuGet パッケージをインストールします。

次のコードにより、すべての構成プロバイダーがクリアされ、2 つの INI ファイルをソースとして IniConfigurationProvider が追加されます。

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

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

IHostEnvironment env = builder.Environment;

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

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

さまざまな構成設定の appsettings.ini ファイルの例を次に示します。

SecretKey="Secret key value"

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

[Logging:LogLevel]
Default=Information
Microsoft=Warning

次のコードにより、前の構成設定がコンソール ウィンドウに書き込まれることによって表示されます。

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

アプリケーションにより、次のサンプル出力が書き込まれます。

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

環境変数構成プロバイダー

appsettings.jsonappsettings.Environment.json、シークレット マネージャーが読み取られた後、EnvironmentVariablesConfigurationProvider により、既定の構成を使用して、環境変数のキーと値のペアから構成が読み込まれます。 そのため、環境から読み取られたキー値は、appsettings.jsonappsettings.Environment.json、シークレット マネージャーをオーバーライドします。

: の区切り記号は、すべてのプラットフォームの環境変数階層キーには対応していません。 たとえば、: の区切り記号は Bash ではサポートされていません。 すべてのプラットフォームでサポートされている二重アンダースコア (__) によって、環境変数内の : 区切り記号はすべて自動的に置き換えられます。

TransientFaultHandlingOptions クラスについて考えてみましょう。

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

次の set コマンドは、SecretKeyTransientFaultHandlingOptions の環境キーと値を設定します。

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

この環境設定は、設定されたコマンド ウィンドウから起動されたプロセスでのみ設定可能です。 Visual Studio で起動された Web アプリでは読み取られません。

Visual Studio 2019 以降では、[起動プロファイル] ダイアログを使用して環境変数を指定できます。

Launch Profiles dialog showing environment variables

次の setx コマンドで、Windows 上の環境キーと値を設定できます。 set とは異なり、setx 設定は保持されます。 /M は、システム環境で変数を設定します。 /M スイッチが使用されていない場合には、ユーザー環境変数が設定されます。

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

上記のコマンドが appsettings.jsonappsettings.Environment.json をオーバーライドすることをテストするには

  • Visual Studio の場合:Visual Studio を終了して再起動します。
  • CLI の場合:新しいコマンド ウィンドウを起動し、dotnet run を入力します。

プレフィックス

環境変数のプレフィックスを指定するには、文字列を指定して AddEnvironmentVariables を呼び出します。

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

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

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

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

上のコードでは以下の操作が行われます。

  • config.AddEnvironmentVariables(prefix: "CustomPrefix_") は既定の構成プロバイダーの後に追加されます。 構成プロバイダーの順序付けの例については、「XML 構成プロバイダー」を参照してください。
  • CustomPrefix_ プレフィックスを使用して設定された環境変数は、既定の構成プロバイダーをオーバーライドします。 これには、プレフィックスのない環境変数が含まれます。

構成のキーと値のペアの読み取り時に、プレフィックスは削除されます。

既定の構成により、DOTNET_ のプレフィックスが付いた環境変数とコマンド ライン引数が読み込まれます。 DOTNET_ プレフィックスは .NET によってDOTNET_アプリの構成に使用されますが、ユーザーの構成には使用されません。

ホストとアプリの構成の詳細については、「.NET 汎用ホスト」を参照してください。

接続文字列のプレフィックス

構成 API には、4つの接続文字列環境変数に対する特別なプロセスルールがあります。 これらの接続文字列は、アプリ環境用の Azure 接続文字列の構成に含まれています。 表に示されたプレフィックスを持つ環境変数は、既定の構成 を使用するとき、または AddEnvironmentVariables にプレフィックスが指定されていない場合に、アプリに読み込まれます。

接続文字列のプレフィックス プロバイダー
CUSTOMCONNSTR_ カスタム プロバイダー
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

表に示す 4 つのプレフィックスのいずれかを使用して、環境変数が検出され構成に読み込まれた場合:

  • 環境変数のプレフィックスを削除し、構成キーのセクション (ConnectionStrings) を追加することによって、構成キーが作成されます。
  • データベースの接続プロバイダーを表す新しい構成のキーと値のペアが作成されます (示されたプロバイダーを含まない CUSTOMCONNSTR_ を除く)。
環境変数キー 変換された構成キー プロバイダーの構成エントリ
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 構成エントリは作成されません。
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: System.Data.SqlClient

launchSettings.json で設定された環境変数

launchSettings.json に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。

Azure App Service の設定

Azure App Service で、[設定]>[構成] ページの [新しいアプリケーション設定] を選択します。 Azure App Service アプリケーションの設定は:

  • 保存時に暗号化され、暗号化されたチャネルで送信されます。
  • 環境変数として公開されます。

コマンド ライン構成プロバイダー

既定の構成を使用して、CommandLineConfigurationProvider は、以下の構成ソースの後にコマンド ライン引数のキーと値のペアから構成を読み込みます:

  • appsettings.jsonappsettings.Environment.json ファイル。
  • Development 環境のアプリのシークレット (Secret Manager)。
  • 環境変数。

既定では、コマンド ラインで設定した構成値により、他のすべての構成プロバイダーで設定された構成値がオーバーライドされます。

Visual Studio 2019 以降では、[起動プロファイル] ダイアログを使用してコマンドライン引数を指定できます。

Launch Profiles dialog showing command-line arguments

コマンド ライン引数

次のコマンドは = を使用してキーと値を設定します:

dotnet run SecretKey="Secret key from command line"

次のコマンドは / を使用してキーと値を設定します:

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

次のコマンドは -- を使用してキーと値を設定します:

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

キーの値:

  • = の後に続ける必要があります。または、値がスペースの後にある場合は、キーのプレフィックスが -- または / である必要があります。
  • = を使用する場合は必要ありません。 たとえば、SomeKey= のようにします。

同じコマンド内では、= を使用するコマンド ライン引数のキーと値のペアを、スペースを使用するキーと値のペアと混在させないでください。

ファイルごとのキーの構成プロバイダー

KeyPerFileConfigurationProvider では、構成のキーと値のペアとしてディレクトリのファイルが使用されます。 キーはファイル名です。 値はファイルの内容です。 ファイルごとのキーの構成プロバイダーは、Docker ホスティングのシナリオで使用されます。

ファイルごとのキーの構成をアクティブにするには、ConfigurationBuilder のインスタンスの AddKeyPerFile 拡張メソッドを呼び出します。 ファイルに対する directoryPath は、絶対パスである必要があります。

オーバーロードによって次のものを指定できます。

  • ソースを構成する Action<KeyPerFileConfigurationSource> デリゲート。
  • ディレクトリを省略可能かどうか、またディレクトリへのパス。

アンダースコア 2 つ (__) は、ファイル名で構成キーの区切り記号として使用されます。 たとえば、ファイル名 Logging__LogLevel__System では、構成キー Logging:LogLevel:System が生成されます。

ホストをビルドするときに ConfigureAppConfiguration を呼び出して、アプリの構成を指定します。

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

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

メモリ構成プロバイダー

MemoryConfigurationProvider では、構成のキーと値のペアとして、メモリ内コレクションが使用されます。

次のコードでは、構成システムにメモリコ レクションが追加されています:

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

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

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

using IHost host = builder.Build();

// Application code should start here.

await host.RunAsync();

上のコードでは、MemoryConfigurationBuilderExtensions.AddInMemoryCollection(IConfigurationBuilder, IEnumerable<KeyValuePair<String,String>>) により既定の構成プロバイダーの後にメモリ プロバイダーが追加されます。 構成プロバイダーの順序付けの例については、「XML 構成プロバイダー」を参照してください。

関連項目