.NET Core 3.1 でバッチを作成する機会があり、Console Application 作成について調べたことのまとめ。
やりたいこと
- .NET Core 3.1 Console Application で DI したい
- 設定ファイルの値をいい感じに使いたい
- NLog の設定をしたい
環境
- Windows 10 Pro
- Visual Studio 2019
- .NET Core 3.1
汎用ホストとは
ASP.NET Core では Web ホストを生成するが、Console Application では、汎用ホストを利用する。
汎用ホストを利用することで、DI や設定ファイルの取得などが簡単に実現できる。
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1
実装
パッケージのインストール
汎用ホストを利用するために必要なパッケージをインストールする。
- Microsoft.Extensions.Hosting
NLog を利用したい場合は、以下パッケージも追加。
- NLog.Extensions.Logging
Program.cs の実装
public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext, config) =>
{
// 引数を取得したい場合
config.AddCommandLine(args);
})
.ConfigureLogging((hostContext, logging) =>
{
logging.ClearProviders();
// appsettings.json から NLog の設定情報を取得する
logging.AddNLog(new NLogLoggingConfiguration(hostContext.Configuration.GetSection("NLog")));
})
.ConfigureServices((hostContext, services) =>
{
// 必要なサービスのDIを記載する
});
Host.CreateDefaultBuilder の規定の動作に何も追加する必要がなければ、ConfigureAppConfiguration、ConfigureLogging、ConfigureServicesは不要。
(ただし、DI したい場合がほとんどだと思うので、ConfigureServices は必要になってくる)
プロジェクトに appsettings.json を追加すれば、既定の動きとして値を取得してくれる。
また、appsettings.json 内に NLog の設定値を記載できる。(NLog.config の追加が不要)
{
// NLog設定
"NLog": {
"throwConfigExceptions": true,
"targets": {
"logfile": {
"type": "File",
"fileName": "C:\\Log\\${shortdate}.log"
},
"logconsole": {
"type": "Console"
}
},
"rules": [
{
"logger": "*",
"minLevel": "Info",
"writeTo": "logconsole"
},
{
"logger": "*",
"minLevel": "Debug",
"writeTo": "logfile"
}
]
},
// 必要なアプリケーション設定値があれば以下に追記する
}
appsettings.json の取り扱い
Host.CreateDefaultBuilder で appsettings.json の読み込みを行ってくれる。
読み込んだ値をクラスに展開(オプションパターン)しておくと、いろいろなところで使えて便利。
appsettings.json の形に合わせたクラスを定義する。
{
"Group": {
"Item1": "ItemValue",
"Item2": 1
}
}
public class AppSettings
{
public Group Group { get; set; }
}
public class Group
{
public string Item1 { get; set; }
public int Item2 { get; set; }
}
実行時に appsettings.json が必要なため、ファイルのプロパティを以下に変更しておく。
- ビルドアクション ⇒ コンテンツ
- 出力ディレクトリにコピー ⇒ 新しい場合はコピーする or 常にコピーする
IHostedService の実装
https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1#ihostapplicationlifetime
上記を参考に、IHostedService を実装する。
logger と options を使えるようにしたサンプル。
public class LifetimeEventsHostedService : IHostedService
{
private readonly IHostApplicationLifetime appLifetime;
private readonly ILogger<LifetimeEventsHostedService> logger;
private readonly IOptions<AppSettings> options;
public LifetimeEventsHostedService(
IHostApplicationLifetime appLifetime
, ILogger<LifetimeEventsHostedService> logger
, IOptions<AppSettings> options)
{
this.appLifetime = appLifetime;
this.logger = logger;
this.options = options;
}
public Task StartAsync(CancellationToken cancellationToken)
{
appLifetime.ApplicationStarted.Register(OnStarted);
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
logger.LogInformation("StartAsync");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
logger.LogInformation("StopAsync");
return Task.CompletedTask;
}
private void OnStarted()
{
logger.LogInformation("OnStarted");
logger.LogInformation($"{options.Value.Group.Item1}{options.Value.Group.Item2}");
}
private void OnStopping()
{
logger.LogInformation("OnStopping");
}
private void OnStopped()
{
logger.LogInformation("OnStopped");
}
}
上記を実装後、Program.cs の ConfigureServices を修正すれば、logger と options の使用が可能。
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<LifetimeEventsHostedService>();
services.Configure<AppSettings>(hostContext.Configuration);
})