LoginSignup
3
4

More than 3 years have passed since last update.

[.NET Core] Console Application で汎用ホストを利用する

Last updated at Posted at 2020-05-24

.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 の実装

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 の追加が不要)

appsettings.json
{
  // 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 の形に合わせたクラスを定義する。

appsettings.json
{
  "Group": {
    "Item1": "ItemValue",
    "Item2": 1
  }
}
AppSettings.cs
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 を使えるようにしたサンプル。

LifetimeEventsHostedService.cs
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 の使用が可能。

Program.cs
.ConfigureServices((hostContext, services) =>
{
    services.AddHostedService<LifetimeEventsHostedService>();
    services.Configure<AppSettings>(hostContext.Configuration);
})

参考URL

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4