コンソール アプリにおける構成情報のロード
以前の記事で、コンソール アプリで、Generic Host を使うことで、appsettings.json から構成情報をロードできることを説明しました。
Generic Host を使うことで、DI(Dependency Injection) 等の多くの機能が使えますが、構成情報のロードは、多くの機能の一部に過ぎません。
検証やデモ等で、簡単なコンソール アプリを開発する場合は、Generic Host の実装は、オーバースペックになるため、今回は、構成情報のロードに絞って説明します。
ConfigurationBuilder による構成情報のロード
プロジェクト直下に appsettings.json
を追加し、プロパティから、[常にコピーする] に設定します。
appsettings.json
に構成情報を定義します。
{
"welcomeMessage": "Hello, configuration!"
}
NuGet から、Microsoft.Extensions.Configuration
、Microsoft.Extensions.Configuration.Json
をプロジェクトへ追加します。
コードでは、ConfigurationBuilder のインスタンスを生成し、AddJsonFile 拡張メソッドで、appsettings.json への参照を追加します。
using Microsoft.Extensions.Configuration;
namespace ConfigurationDemoConsoleApp001;
internal class Program
{
static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var welcomeMessage = configuration["welcomeMessage"]
?? throw new ArgumentNullException("welcomeMessage not found.");
Console.WriteLine(welcomeMessage);
Console.ReadLine();
}
}
他のソース: 環境変数、コマンドライン オプションからも構成情報を取得したい場合は、同様に Microsoft.Extensions.Configuration.EnvironmentVariables
、Microsoft.Extensions.Configuration.CommandLine
を NuGet から取得、プロジェクトへ追加し、以下のコードを書きます。
using Microsoft.Extensions.Configuration;
namespace ConfigurationDemoConsoleApp001;
internal class Program
{
static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
var welcomeMessage = configuration["welcomeMessage"]
?? throw new ArgumentNullException("welcomeMessage not found.");
Console.WriteLine(welcomeMessage);
Console.ReadLine();
}
}
AddEnvironmentVariables 拡張メソッドで、環境変数のロード、AddCommandLine 拡張メソッドで、コマンドライン オプションから構成情報を取得しています。 これらの拡張メソッドの順番にも意味があり、追加順で構成情報のロードをオーバーライドします。つまり、このコードの場合では、同一の値が、appsettings.json と、環境変数で定義されていた場合は、環境変数の値が適用されます。さらに、コマンドライン オプションでも同一の値が定義されていた場合は、コマンドライン オプションの値が適用されます。
Generic Host における構成情報ロードの実装
ここで、参考として Generic Host の実装を見てみます。 以下のコードのように Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder ファクトリ メソッドで、HostBuilder のインスタンスを生成します。
public class Program
{
public static void Main(string[] args)
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// DI
services.AddHostedService<Worker>();
})
.Build();
host.Run();
}
}
この CreateDefaultBuilder の実装は、以下から参照できます。
HostingHostBuilderExtensions.cs の ApplyDefaultAppConfiguration メソッドで、構成情報のロードが定義されています。
internal static void ApplyDefaultAppConfiguration(HostBuilderContext hostingContext, IConfigurationBuilder appConfigBuilder, string[]? args)
{
IHostEnvironment env = hostingContext.HostingEnvironment;
bool reloadOnChange = GetReloadConfigOnChangeValue(hostingContext);
appConfigBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);
if (env.IsDevelopment() && env.ApplicationName is { Length: > 0 })
{
try
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
appConfigBuilder.AddUserSecrets(appAssembly, optional: true, reloadOnChange: reloadOnChange);
}
catch (FileNotFoundException)
{
// The assembly cannot be found, so just skip it.
}
}
appConfigBuilder.AddEnvironmentVariables();
AddCommandLineConfig(appConfigBuilder, args);
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Calling IConfiguration.GetValue is safe when the T is bool.")]
static bool GetReloadConfigOnChangeValue(HostBuilderContext hostingContext) => hostingContext.Configuration.GetValue("hostBuilder:reloadConfigOnChange", defaultValue: true);
}
appsettings..json のサポートが記述されています。 IHostEnvironment.EnvironmentName は、起動プロファイルの選択により、Development, Production の値が入り、開発環境では、appsettings.Development.json を参照するといったように、実行環境に応じて、参照する appsettings.json を変更できます。
このあたりは、過去に、以下の記事に書いています。
また、AddUserSecrets により、ユーザーシークレットからのロードのサポートも記述されています。
このコードから、Generic Host を使用する場合、appSettings.json、appsettings..json、ユーザーシークレット、環境変数、コマンドライン オプションの順で、構成情報のロードの優先順位が高くなることが分かります。
以上、参考までに。
コメント (0)
コメントの投稿