きなこもち.net

.NET Framework × UiPath,Orchestrator × Azure × AWS × Angularなどの忘備録

dotnet core × Startup × Configureの勉強

Goal

.NET Coreの起動処理の復習。主に、Configure回りを行う。

.NET での汎用ホスト

.NET での汎用ホストを読み込む。

導入

Worker サービス テンプレートを使用すると、.NET 汎用ホスト HostBuilder が作成されます。 汎用ホストは、コンソール アプリなど、他の種類の .NET アプリケーションで使用できます。

コンソールアプリケーションでも、汎用ホストを利用する。しっかりと公式ドキュメントに記載されていた。

ホストは通常、Program クラス内のコードによって構成、ビルド、および実行されます。

Programファイル内で、ホストオブジェクトの設定を行い、実行する。Windows Service用のプロジェクトテンプレートを選択した場合、ProgramファイルのほかにBackgroundServiceを継承したWorkerクラスが作成される。通常は、このWorkerクラスのRunメソッドを実装する。

public abstract class BackgroundService : IHostedService, IDisposable

BackgroundServiceは、IHostedServiceとIDisposableインターフェースを継承した抽象クラス。 似たようなことをしたい場合、IHostedServiceインターフェースを実装したクラスを用意することで実現することができる。

    class Program :IHostedService
    {
        static void Main(string[] args)
        {
            Host.CreateDefaultBuilder().ConfigureServices(services =>
            {
                services.AddHostedService<Program>();
            }).Build().Run();
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            throw new NotImplementedException();
        }
    }

[疑問]Runメソッドはどこで定義されている?

汎用HostをBuildした後、Hostクラスのインスタンスが戻されるが、Hostクラス自体には、Runメソッドは定義されていない。代わりに、HostingAbstractionsHostExtensions.cs クラスに拡張メソッドとして定義されている。これが呼ばれている。

[疑問]RunとStartの違い

Runメソッドのほかに、Startメソッドが定義されている。これらの違いは、XMLドキュメントから読み取れた。

Run: Runs an application and returns a Task that only completes when the token is triggered or shutdown is triggered. The instance is disposed of after running.

Start: Starts the host synchronously.

Runメソッドで開始された処理は、Host側(Windows Serviceとして考えたほうがよい?)が停止シグナルを受け取るまで動き続ける。Startメソッドは、処理が終われば、終了するという違いがある。

コンテナにデプロイしたコンソールアプリがずっと動き続けていた理由がわかった。。。Runしていたからだ・・・

builderの各種設定

規定のBuilder設定に詳細があるが、汎用ホストのDefaultBuilderを作成すると、appsettings.jsonや、プレフィックスDOTNET_が付く環境変数、引数を読み込み、Key-Value形式でConfigurationに格納してくれる。

[疑問]コマンドライン引数もConfigurationに登録されるの?

詳しくは、CommandLineConfigurationProviderで定義されている処理を確認する。

  • 利用できるオプション -, --, /
    • 規定の動作(※key mapping利用しない場合)
      • -key value -> ignore

        If the switch starts with a single "-" and it isn't in given mappings , it is an invalid usage so ignore it

      • -key=value -> FormatException!

        If the switch starts with a single "-" and it isn't in given mappings , it is an invalid usage

      • --key value -> mapped

      • --key=value -> mapped

      • /key value -> mapped

      • /key=value -> mapped

      • value -> ignore

      • key=value -> mapped

        • これも可
      • key value -> ignore
        • これは不可

※Keyの後ろに、Valueがない場合は、すべて無視される。 ※key mappingを利用すれば、さらに柔軟なマッピング処理を定義可能

mappingされた引数は、Configuration.GetSection("key").Valueで取得することができる。

なお、Key-Value配列では、StringComparer.OrdinalIgnoreCaseオプションが付けられているため、Keyの大文字小文字を意識しなくて良い。 new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);

[メモ]引数の取得

 private readonly string _arg1;
 public Program(IConfiguration configuration)
 {
     _arg1 = configuration.GetSection("key1").Value;
 }