トレーニング
ASP.NET の構成ビルダー
Stephen Molloy および Rick Anderson 著
構成ビルダーは、ASP.NET アプリが外部ソースから構成値を取得するための最新の機動的なしくみを提供します。
構成ビルダー:
- .NET Framework 4.7.1 以降で使用できます。
- 構成値を読み取るための柔軟なメカニズムを提供します。
- コンテナーとクラウドに重点を置いた環境に移行するアプリの基本的なニーズの一部に対処します。
- .NET 構成システムで以前利用できなかったソース (Azure Key Vault や環境変数など) から描画することで、構成データの保護を強化するために使用できます。
構成ビルダーで処理できる一般的なシナリオは、キー/値パターンに従う構成セクションの基本的なキー/値置換メカニズムを提供することです。 ConfigurationBuilders の .NET Framework の概念は、特定の構成セクションまたはパターンに限定されません。 ただし、Microsoft.Configuration.ConfigurationBuilders
(github、NuGet) の構成ビルダーの多くは、キーと値のパターン内で動作します。
次の設定は、Microsoft.Configuration.ConfigurationBuilders
内のすべてのキーと値の構成ビルダーに適用されます。
構成ビルダーは、キー/値情報の外部ソースを使用して、構成システムの選択したキー/値要素を設定します。 具体的には、<appSettings/>
セクションと <connectionStrings/>
セクションは、構成ビルダーから特別な処理を受けます。 ビルダーは次の 3 つのモードで動作します。
Strict
- 既定のモード。 このモードでは、構成ビルダーは既知のキー/値中心の構成セクションでのみ動作します。Strict
モードでは、セクション内の各キーが列挙されます。 外部ソースで一致するキーが見つかった場合:- 構成ビルダーは、結果の構成セクションの値を外部ソースからの値に置き換えます。
Greedy
- このモードは、Strict
モードと密接に関連しています。 元の構成に既に存在するキーに限定されるのではありません。- 構成ビルダーは、外部ソースから結果の構成セクションにすべてのキーと値のペアを追加します。
Expand
- 構成セクション オブジェクトに解析される前に、生の XML を操作します。 これは、文字列内のトークンの拡張と考えることができます。 パターン${token}
に一致する生の XML 文字列の任意の部分が、トークン拡張の候補となります。 外部ソースに対応する値が見つからない場合、トークンは変更されません。 このモードのビルダーは、<appSettings/>
セクションと<connectionStrings/>
セクションに限定されません。
web.config の次のマークアップにより、EnvironmentConfigBuilder が Strict
モードで有効になります。
<configuration>
<configSections>
<section name="configBuilders"
type="System.Configuration.ConfigurationBuildersSection,
System.Configuration, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
restartOnExternalChanges="false" requirePermission="false" />
</configSections>
<configBuilders>
<builders>
<add name="MyEnvironment"
type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Environment,
Version=1.0.0.0, Culture=neutral" />
</builders>
</configBuilders>
<appSettings configBuilders="MyEnvironment">
<add key="ServiceID" value="ServiceID value from web.config" />
<add key="ServiceKey" value="ServiceKey value from web.config" />
</appSettings>
<connectionStrings configBuilders="MyEnvironment">
<add name="default" connectionString="Data Source=web.config/mydb.db" />
</connectionStrings>
次のコードは、前述の web.config ファイルで示した <appSettings/>
と <connectionStrings/>
を読み取ります。
using System;
using System.Configuration;
using System.Web.UI;
namespace MyConfigBuilders
{
public partial class About : Page
{
public string ServiceID { get; set; }
public string ServiceKey { get; set; }
public string ConString { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
ServiceID = ConfigurationManager.AppSettings["ServiceID"];
ServiceKey = ConfigurationManager.AppSettings["ServiceKey"];
ConString = ConfigurationManager.ConnectionStrings["default"]
?.ConnectionString;
}
}
}
上記のコードでは、プロパティ値が次の値に設定されます。
- キーが環境変数内に設定されていない場合の web.config ファイル内の値。
- 環境変数の値 (設定されている場合)。
たとえば、ServiceID
に次のものが格納されます。
- 環境変数
ServiceID
が設定されていない場合は、"Web.config からの ServiceID 値"。 ServiceID
環境変数の値 (設定されている場合)。
次の図は、環境エディターで設定された前述の web.config ファイルからの <appSettings/>
のキー/値を示しています。
注: 環境変数の変更を確認するには、Visual Studio を終了して再起動する必要がある場合があります。
キー プレフィックスを使用すると、次の理由でキーの設定を簡略化できます。
- .NET Framework の構成は複雑で入れ子になっています。
- 外部のキー/値ソースは、一般的に基本的であり、本質的にフラットです。 たとえば、環境変数は入れ子になっていません。
環境変数を使用して構成に <appSettings/>
と <connectionStrings/>
の両方を挿入するには、次のいずれかの方法を使用します。
- 既定の
Strict
モードでEnvironmentConfigBuilder
を使用し、構成ファイル内で適切なキー名を使用します。 上記のコードとマークアップでは、このアプローチを採用しています。 この方法を使用すると、<appSettings/>
と<connectionStrings/>
の両方で同じ名前のキーを持つすることはできません。 Greedy
モードで異なるプレフィックスを持つ 2 つのEnvironmentConfigBuilder
とstripPrefix
を使用します。 この方法では、アプリは構成ファイルを更新する必要なく、<appSettings/>
と<connectionStrings/>
を読み取れます。 次のセクション stripPrefix では、これを行う方法を示します。Greedy
モード内で異なるプレフィックスを持つ 2 つのEnvironmentConfigBuilder
を使用します。 この方法では、キー名がプレフィックスによって異なる必要があり、重複するキー名を持たせることはできません。 次に例を示します。
<configuration>
<configSections>
<section name="configBuilders"
type="System.Configuration.ConfigurationBuildersSection,
System.Configuration, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
restartOnExternalChanges="false" requirePermission="false" />
</configSections>
<configBuilders>
<builders>
<add name="AS_Environment" mode="Greedy" prefix="AppSetting_"
type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Environment" />
<add name="CS_Environment" mode="Greedy" prefix="ConnStr_"
type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Environment" />
</builders>
</configBuilders>
<appSettings configBuilders="AS_Environment">
<add key="AppSetting_ServiceID" value="ServiceID value from web.config" />
<add key="AppSetting_default" value="AppSetting_default value from web.config" />
</appSettings>
<connectionStrings configBuilders="CS_Environment">
<add name="ConnStr_default" connectionString="Data Source=web.config/mydb.db" />
</connectionStrings>
上記のマークアップでは、同じフラット キー/値ソースを使用して、2 つの異なるセクションの構成を設定できます。
次の図は、環境エディターで設定された前述の web.config ファイルからの <appSettings/>
と <connectionStrings/>
のキー/値を示しています。
次のコードは、前述の web.config ファイルに含まれている <appSettings/>
と <connectionStrings/>
のキー/値を読み取ります。
public partial class Contact : Page
{
public string ServiceID { get; set; }
public string AppSetting_default { get; set; }
public string ConString { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
ServiceID = ConfigurationManager.AppSettings["AppSetting_ServiceID"];
AppSetting_default = ConfigurationManager.AppSettings["AppSetting_default"];
ConString = ConfigurationManager.ConnectionStrings["ConnStr_default"]
?.ConnectionString;
}
}
上記のコードでは、プロパティ値が次の値に設定されます。
- キーが環境変数内に設定されていない場合の web.config ファイル内の値。
- 環境変数の値 (設定されている場合)。
たとえば、前述の web.config ファイルを使用すると、前述の環境エディター イメージのキー/値、前述のコード、次の値が設定されます。
Key | Value |
---|---|
AppSetting_ServiceID | 環境変数からの AppSetting_ServiceID |
AppSetting_default | 環境からの AppSetting_default 値 |
ConnStr_default | 環境からの ConnStr_default 変数 |
stripPrefix
: ブール値 (既定値は false
)。
上記の XML マークアップは、アプリ設定を接続文字列から分離しますが、指定したプレフィックスを使用するには、web.config ファイル内のすべてのキーが必要です。 たとえば、プレフィックス AppSetting
は、ServiceID
キー ("AppSetting_ServiceID") に追加する必要があります。 stripPrefix
を指定すると、このプレフィックスは、web.config ファイル内では使用されません。 このプレフィックスは、構成ビルダーのソース (環境など) で必要です。ほとんどの開発者が stripPrefix
を使用することを想定しています。
通常、アプリケーションはプレフィックスを削除します。 次の web.config は、プレフィックスを削除します。
<configuration>
<configSections>
<section name="configBuilders"
type="System.Configuration.ConfigurationBuildersSection,
System.Configuration, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
restartOnExternalChanges="false" requirePermission="false" />
</configSections>
<configBuilders>
<builders>
<add name="AS_Environment" mode="Greedy" prefix="AppSetting_"
stripPrefix="true"
type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Environment,
Version=1.0.0.0, Culture=neutral" />
<add name="CS_Environment" mode="Greedy" prefix="ConnStr_"
stripPrefix="true"
type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Environment,
Version=1.0.0.0, Culture=neutral" />
</builders>
</configBuilders>
<appSettings configBuilders="AS_Environment">
<add key="ServiceID" value="ServiceID value from web.config" />
<add key="default" value="AppSetting_default value from web.config" />
</appSettings>
<connectionStrings configBuilders="CS_Environment">
<add name="default" connectionString="Data Source=web.config/mydb.db" />
</connectionStrings>
前述の web.config ファイルでは、default
キーは <appSettings/>
と <connectionStrings/>
の両方に含められます。
次の図は、環境エディターで設定された前述の web.config ファイルからの <appSettings/>
と <connectionStrings/>
のキー/値を示しています。
次のコードは、前述の web.config ファイルに含まれている <appSettings/>
と <connectionStrings/>
のキー/値を読み取ります。
public partial class About2 : Page
{
public string ServiceID { get; set; }
public string AppSetting_default { get; set; }
public string ConString { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
ServiceID = ConfigurationManager.AppSettings["ServiceID"];
AppSetting_default = ConfigurationManager.AppSettings["default"];
ConString = ConfigurationManager.ConnectionStrings["default"]
?.ConnectionString;
}
}
上記のコードでは、プロパティ値が次の値に設定されます。
- キーが環境変数内に設定されていない場合の web.config ファイル内の値。
- 環境変数の値 (設定されている場合)。
たとえば、前述の web.config ファイルを使用すると、前述の環境エディター イメージのキー/値、前述のコード、次の値が設定されます。
Key | Value |
---|---|
ServiceID | 環境変数からの AppSetting_ServiceID |
default | 環境からの AppSetting_default 値 |
default | 環境からの ConnStr_default 変数 |
tokenPattern
: string (既定値は @"\$\{(\w+)\}"
)
ビルダーの Expand
動作では、生の XML で ${token}
のようなトークンが検索されます。 検索は、既定の正規表現 @"\$\{(\w+)\}"
を使用して実行されます。 \w
と照合される文字のセットは XML よりも厳密であり、多くの構成ソースで許可されます。 トークン名に @"\$\{(\w+)\}"
を超える文字数が必要な場合、tokenPattern
を使用します。
tokenPattern
: String:
- 開発者は、トークンの照合に使用される正規表現を変更できます。
- 適切な形式の危険でない正規表現であることを確認するための検証は行われません。
- キャプチャ グループを含む必要があります。 正規表現全体がトークン全体と一致している必要があります。 最初のキャプチャは、構成ソースで検索するトークン名である必要があります。
<add name="Environment"
[mode|prefix|stripPrefix|tokenPattern]
type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Environment" />
- 構成ビルダーの中で最も簡単です。
- 環境から値を読み取ります。
- バイナリ ファイルには、追加の構成オプションはありません。
name
属性値は任意です。
注: Windows コンテナー環境では、実行時に設定された変数は、EntryPoint プロセス環境にのみ挿入されます。 サービスまたは EntryPoint 以外のプロセスとして実行されるアプリは、コンテナー内のメカニズムを介して挿入されない限り、これらの変数を取得しません。 IIS/ASP.NET ベースのコンテナーの場合、現在のバージョンの ServiceMonitor.exe は、これを DefaultAppPool 内でのみ処理します。 他の Windows ベースのコンテナー バリアントでは、EntryPoint 以外のプロセス用に独自のインジェクション メカニズムを開発する必要がある場合があります。
警告
パスワード、機密性の高い接続文字列、またはその他の機密データはソース コードに格納しないでください。 運用環境のシークレットは、開発またはテストに使用しないでください。
<add name="UserSecrets"
[mode|prefix|stripPrefix|tokenPattern]
(userSecretsId="{secret string, typically a GUID}" | userSecretsFile="~\secrets.file")
[optional="true"]
type="Microsoft.Configuration.ConfigurationBuilders.UserSecretsConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.UserSecrets" />
上記の XML では、userSecretsFile
パスは、~/
または ~\
も使用できます。 たとえば、パスは userSecretsFile="~/secrets.file
のように記述できます。 詳細については、ConfigurationBuilders Utils クラスを参照してください。
この構成ビルダーは、ASP.NET Core Secret Manager と同様の機能を提供します。
UserSecretsConfigBuilder は .NET Framework プロジェクトで使用できますが、シークレット ファイルを指定する必要があります。 または、UserSecretsId
プロパティをプロジェクト ファイル内に定義し、読み取り用の正しい場所に生のシークレット ファイルを作成することもできます。 外部の依存関係をプロジェクトから除外するために、シークレット ファイルは XML 形式です。 XML 形式は実装の詳細であり、形式に依存しないようにする必要があります。 secrets.json ファイルを .NET Core プロジェクトと共有する必要がある場合は、SimpleJsonConfigBuilder の使用を検討してください。 .NET Core の SimpleJsonConfigBuilder
形式も、変更対象の実装の詳細と見なす必要があります。
UserSecretsConfigBuilder
の構成属性:
userSecretsId
- これは、XML シークレット ファイルを識別するための推奨される方法です。 これは、UserSecretsId
プロジェクト プロパティを使用してこの識別子を格納する .NET Core と同様に機能します。 文字列は一意である必要があります。GUID である必要はありません。 この属性を使用すると、UserSecretsConfigBuilder
は、既知のローカルの場所 (%APPDATA%\Microsoft\UserSecrets\<UserSecrets Id>\secrets.xml
) でこの識別子に属するシークレット ファイルを検索します。userSecretsFile
- シークレットを含むファイルを指定する省略可能な属性。~
文字は、開始時にアプリケーション ルートを参照するために使用できます。 この属性かuserSecretsId
属性のどちらかが必要です。 両方を指定した場合は、userSecretsFile
が優先されます。optional
: ブール値、既定値true
- シークレット ファイルが見つからない場合に、例外を回避します。name
属性値は任意です。
ファイルの形式は次のとおりです。
<?xml version="1.0" encoding="utf-8" ?>
<root>
<secrets ver="1.0">
<secret name="secret key name" value="secret value" />
</secrets>
</root>
<add name="AzureKeyVault"
[mode|prefix|stripPrefix|tokenPattern]
(vaultName="MyVaultName" |
uri="https:/MyVaultName.vault.azure.net")
[version="secrets version"]
[preloadSecretNames="true"]
type="Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Azure" />
AzureKeyVaultConfigBuilder は、Azure Key Vault に格納されている値を読み取ります。
vaultName
は必須です (コンテナーの名前またはコンテナー URI のいずれか)。 他の属性では、接続先のコンテナーを制御できますが、アプリケーションが Microsoft.Azure.Services.AppAuthentication
と連携する環境で実行されていない場合にのみ必要です。 Azure サービス認証ライブラリは、可能であれば、実行環境から接続情報を自動的に取得するために使用されます。 接続文字列を指定することで、接続情報の自動取得をオーバーライドできます。
vaultName
-uri
が指定されていない場合は必須。 キーと値のペアの読み取り元となる Azure サブスクリプション内のコンテナーの名前を指定します。uri
- 指定したuri
値を使用して他の Key Vault プロバイダーに接続します。 指定しない場合、Azure (vaultName
) がコンテナー プロバイダーです。version
- Azure Key Vault には、シークレット用のバージョン管理機能が用意されています。version
を指定した場合、ビルダーは、このバージョンに一致するシークレットのみを取得します。preloadSecretNames
- 既定では、このビルダーは、初期化時にキー コンテナー内のすべてのキー名に対してクエリを実行します。 すべてのキー値は読み取らないようにするには、この属性をfalse
に設定します。 これをfalse
に設定すると、シークレットは一度に 1 つずつ読み取られます。 シークレットを一度に 1 つずつ読み取ると、コンテナーで "Get" アクセスは許可され、"List" アクセスは許可されない場合に便利です。 注:Greedy
モードを使用する場合は、preloadSecretNames
はtrue
(既定値) にする必要があります。
<add name="KeyPerFile"
[mode|prefix|stripPrefix|tokenPattern]
(directoryPath="PathToSourceDirectory")
[ignorePrefix="ignore."]
[keyDelimiter=":"]
[optional="false"]
type="Microsoft.Configuration.ConfigurationBuilders.KeyPerFileConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.KeyPerFile" />
KeyPerFileConfigBuilder は、ディレクトリのファイルを値のソースとして使用する基本的な構成ビルダーです。 ファイルの名前がキーであり、コンテンツが値です。 この構成ビルダーは、調整されたコンテナー環境で実行する場合に便利です。 Docker Swarm や Kubernetes などのシステムは、secrets
をファイル単位のキー方式で調整された Windows コンテナーに提供します。
属性の詳細は次のとおりです。
directoryPath
- 必須。 値を検索するパスを指定します。 Docker Client for Windows シークレットは、既定で C:\ProgramData\Docker\secrets ディレクトリに格納されます。ignorePrefix
- このプレフィックスで始まるファイルは除外されます。 既定値は "ignore" です。keyDelimiter
- 既定値はnull
です。 指定した場合、構成ビルダーはディレクトリの複数のレベルを横断し、この区切り記号を使用してキー名を作成します。 この値がnull
の場合、構成ビルダーはディレクトリの最上位レベルのみを参照します。optional
- 既定値はfalse
です。 ソース ディレクトリが存在しない場合に構成ビルダーがエラーを発生させるかどうかを指定します。
警告
パスワード、機密性の高い接続文字列、またはその他の機密データはソース コードに格納しないでください。 運用環境のシークレットは、開発またはテストに使用しないでください。
<add name="SimpleJson"
[mode|prefix|stripPrefix|tokenPattern]
jsonFile="~\config.json"
[optional="true"]
[jsonMode="(Flat|Sectional)"]
type="Microsoft.Configuration.ConfigurationBuilders.SimpleJsonConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Json" />
.NET Core プロジェクトでは、構成に JSON ファイルが頻繁に使用されます。 SimpleJsonConfigBuilder ビルダーを使用すると、.NET Core JSON ファイルを .NET Framework で使用できます。 この構成ビルダーは、フラット キー/値ソースから .NET Framework 構成の特定のキー/値領域への基本的なマッピングを提供します。 この構成ビルダーでは、階層構成は提供されません。 JSON バッキング ファイルはディクショナリに似ていますが、複雑な階層オブジェクトではありません。 複数レベルの階層ファイルを使用できます。 このプロバイダーは、:
を区切り記号として使用して、各レベルでプロパティ名を追加することで、深度に flatten
を適用してフラットにします。
属性の詳細は次のとおりです。
jsonFile
- 必須。 読み取る JSON ファイルを指定します。~
文字は、開始時にアプリのルートを参照するために使用できます。optional
- ブール値 (既定値はtrue
)。 JSON ファイルが見つからない場合に例外をスローしないようにします。jsonMode
-[Flat|Sectional]
=Flat
は既定値です。jsonMode
がFlat
の場合、JSON ファイルは単一のフラットなキーと値のソースです。EnvironmentConfigBuilder
とAzureKeyVaultConfigBuilder
も、それぞれ単一のフラットなキーと値のソースです。SimpleJsonConfigBuilder
がSectional
モードで構成されている場合、次のようになります。- JSON ファイルは概念的に最上位レベルで複数のディクショナリに分割されます。
- 各ディクショナリは、添付されている最上位のプロパティ名と一致する構成セクションにのみ適用されます。 次に例を示します。
{
"appSettings" : {
"setting1" : "value1",
"setting2" : "value2",
"complex" : {
"setting1" : "complex:value1",
"setting2" : "complex:value2",
}
}
}
aspnet/MicrosoftConfigurationBuilders GitHub リポジトリ内での ConfigurationBuilders の実行順序を参照してください。
構成ビルダーがニーズを満たしていない場合は、カスタムのビルダーを作成できます。 KeyValueConfigBuilder
基底クラスは、置換モードとほとんどのプレフィックスの問題を処理します。 実装するプロジェクトには、次のみが必要です。
- 基底クラスから継承し、
GetValue
とGetAllValues
を介してキーと値のペアの基本的なソースを実装します。 - Microsoft.Configuration.ConfigurationBuilders.Base をプロジェクトに追加します。
using Microsoft.Configuration.ConfigurationBuilders;
using System.Collections.Generic;
public class MyCustomConfigBuilder : KeyValueConfigBuilder
{
public override string GetValue(string key)
{
// Key lookup should be case-insensitive, because most key/value collections in
// .NET Framework config sections are case-insensitive.
return "Value for given key, or null.";
}
public override ICollection<KeyValuePair<string, string>> GetAllValues(string prefix)
{
// Populate the return collection.
return new Dictionary<string, string>() { { "one", "1" }, { "two", "2" } };
}
}
KeyValueConfigBuilder
基底クラスは、ほとんどの動作を提供し、キーと値の構成ビルダー全体で一貫性のある動作を提供します。
その他のリソース
ドキュメント
-
構成 API を使用して、ASP.NET Core アプリで AppSettings を構成する方法について説明します。
-
ASP.NET Core での開発におけるアプリ シークレットの安全な保存
ASP.NET Core アプリの開発中に機密情報を格納および取得する方法について説明します。