1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

.NETの汎用ホスト(Generic Host)

Last updated at Posted at 2024-11-12

.NET 汎用ホスト(Generic Host)とは

''ホスト'' とは、次のようなアプリのリソースと有効期間機能をカプセル化するオブジェクトです。
依存関係の挿入 (DI)
ログの記録
構成
アプリのシャットダウン
IHostedService の実装

やってみよう。

NuGet

Microsoft.Extensions.Hosting をパッケージに追加します。

ホストの作成

ホストを作るにはビルダーを使います。

Program.cs
HostApplicationBuilder hostBuilder = Host.CreateApplicationBuilder(args);

Host.CreateDefaultBuilder()もあるけど?

依存関係の挿入(DI)

サービスコンテナで依存関係を挿入できry

構成(Configuration)

Host.CreateApplicationBuilder(String[]) メソッドにより、優先度の高い方から低い方へ、次の順序でアプリの既定の構成が提供されます。

  1. コマンドライン構成プロバイダーを使用するコマンドライン引数。
  2. 環境変数構成プロバイダーを使用する環境変数。
  3. Development 環境でアプリが実行される際の App シークレット。
  4. JSON 構成プロバイダーを使用する appsettings.json。
  5. JSON 構成プロバイダーを使用する appsettings.Environmentjson。 たとえば、appsettings.Production.json および appsettings.Development.json。
  6. ChainedConfigurationProvider: 既存の IConfiguration をソースとして追加します。

アプリ独自の設定をappsettings.jsonに定義。

appsettings.json
{
  "lang": "ja",
  "LogOptions": {
    "SingleLine": true,
    "TimestampFormat": "yyyy-MM-dd HH:mm:ss "
  }
}

ログの記録(Logging)のログレベルは、環境毎のファイルに定義。

appsettings.Development.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsft": "Information"
    }
  }
}

appsettings.jsonの内容をマップするクラスを実装。

AppSettings.cs
    internal class AppSettings
    {
        public string Lang { set; get; } = "en";
        public LogOptions LogOptions { set; get; } = new LogOptions();
    }

    internal class LogOptions
    {
        public bool SingleLine { set; get; } = false;
        public string TimestampFormat { set; get; } = "HH:mm:ss ";
    }

設定をマップする

Program.cs
var appSettings = hostBuilder.Configuration.Get<AppSettings>() ?? new AppSettings();

設定の一部分だけをマップする

Program.cs
var logOptions = hostBuilder.Configuration.GetSection(nameof(LogOptions)).Get<LogOptions>() ?? new LogOptions();

構成(Configuration)は、サービスコンテナンに登録されてます。

Program.cs
//using IHost host = hostBuilder.Build();
var configuration = host.Services.GetService<IConfiguration>()!;

ログの記録(Logging)

例として、ログプロバイダーとしてSimpleConsoleを追加します。(log4net、Nlogなども利用可)
ログレベルは、appsettings.Development.jsonの /Logging/LogLevelに設定した内容が反映されます。
出力オプションは構成(Configuration)から取得した内容を設定しています。

Program.cs
hostBuilder.Logging.ClearProviders().AddSimpleConsole(options =>
{
    options.SingleLine = appSettings.LogOptions.SingleLine;
    options.TimestampFormat = appSettings.LogOptions.TimestampFormat;
});

ロガーは、サービスコンテナンに登録されてます。

Program.cs
//using IHost host = hostBuilder.Build();
var logger = host.Services.GetService<ILogger<Program>>()!;

ローカライズ

2024/11/18更新!

NuGet

リソースファイル追加

MessageResources.reex
<root>
  <data name="hello_world" xml:space="preserve">
    <value>こんにちは、世界!</value>
  </data>
</root>
MessageResources.en.reex
<root>
  <data name="hello_world" xml:space="preserve">
    <value>Hello World!</value>
  </data>
</root>

サービス作成

MessageService.cs
internal class MessageService(IStringLocalizer<MessageResources> localizer)
{
    internal string this[string key]
    {
        get
        {
            return localizer[key];
        }
    }
}

ホストの作成

Program.cs
// カルチャの設定
CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(appSettings.Lang);

// ローカライゼーションサービスの追加
hostBuilder.Services.AddLocalization();

// MessageServiceを登録
hostBuilder.Services.AddSingleton<MessageService>();

で利用してみます。

IHostedServiceの実装

ホストが起動すると、サービス コンテナーのホステッド サービスのコレクションに登録されている IHostedService の各実装で IHostedService.StartAsync が呼び出されます。
アプリの相互依存するすべてのリソースを 1 つのオブジェクトに含める主な理由は、アプリの起動と正常なシャットダウンの制御の有効期間の管理のためです。

IHostedServiceの実装HostedServiceを作成します。

HostedService.cs
    internal class HostedService(
        //コンストラクタの引数はサービスコンテナによってDIされる
        IHostApplicationLifetime hostApplicationLifetime,
        IHostEnvironment environment,
        IHostLifetime hostLifetime,
        IConfiguration configuration,
        ILogger<HostedService> logger,
        MessageService messageService
    ) : IHostedService
    { 
        public Task StartAsync(CancellationToken cancellationToken)
        {
            logger.LogTrace("HostedService.StartAsync");

            // 構成ファイルの中から独自設定を取得
            var appSettings = configuration.Get<AppSettings>() ?? new AppSettings();
            logger.LogDebug(appSettings.Lang);

            // ローカライズされたメッセージの取得
            logger.LogDebug(messageService["hello_world"]);

            // アプリを終了する
            hostApplicationLifetime.StopApplication();

            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            logger.LogTrace("HostedService.StopAsync");
            return Task.CompletedTask;
        }
    }

実装したHostedServiceをサービスコンテナンに登録します。

Program.cs
hostBuilder.Services.AddHostedService<HostedService>();

IHostEnvironment

TODO

IHostApplicationLifetime

アプリケーションを終了するのにつかう

IHostLifetime

TODO

ホストの起動

Program.cs
using IHost host = hostBuilder.Build();
await host.RunAsync();
1
1
1

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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?