.NET Generic Host 入門
結論
Generic Host は、.NETアプリの起動と有効期間(ライフタイム)をまとめて扱う土台です。DI(依存性注入)、設定、ログ、バックグラウンド処理、アプリの停止処理をひとまとめに管理します。
- 新しい非Webアプリでは
Host.CreateApplicationBuilder(args)から始める - ASP.NET Coreの
WebApplicationBuilderも同じ考え方の上にWeb機能を追加したもの - 短命なジョブにまで毎回使う必要はない(小さなツールなら不要)
Generic Hostが提供するもの
| 機能 | 内容 | メリット |
|---|---|---|
| DI | IServiceCollection からサービスを組み立て |
new の連鎖を減らせる |
| 設定 | appsettings.json、環境変数、コマンドライン引数を統合 |
環境ごとの差分を扱いやすい |
| ログ | ILogger<T> の基盤を提供 |
出力先を後から差し替えやすい |
| Hosted Service | IHostedService/BackgroundService の起動と停止 |
常駐処理をアプリ本体と分離 |
| ライフタイム | 開始・停止の管理(Ctrl+C、SIGTERM対応) | 終了処理を統一できる |
Builderの違い
| エントリポイント | 主な用途 | いつ使うか |
|---|---|---|
Host.CreateApplicationBuilder(args) |
コンソール/worker(新規) | 新しい非Webアプリならこれ |
Host.CreateDefaultBuilder(args) |
コンソール/worker(既存) | 既存の拡張メソッド主体のコード |
WebApplication.CreateBuilder(args) |
ASP.NET Core Web/API | Webアプリならこれ |
CreateApplicationBuilder と CreateDefaultBuilder は書き方の流儀が違うだけで、コア機能は同じです。新規なら CreateApplicationBuilder が素直です。
処理の流れ
args/環境変数/appsettings.json
↓
Host.CreateApplicationBuilder(args)
↓
builder.Configuration / builder.Services / builder.Logging
↓
builder.Services にサービスや BackgroundService を登録
↓
builder.Build() → IHost を取得
↓
Run() / RunAsync() → 起動・停止・Ctrl+C・SIGTERMを管理
既定で以下のものが自動的に組み込まれます:
appsettings.json、appsettings.{Environment}.json、環境変数、コマンドライン引数- Console、Debug、EventSource、EventLog(Windowsのみ)へのログ出力
- Development環境でのscope検証と依存関係検証
最小構成:短命なコンソールツール
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddSingleton<JobRunner>();
using IHost host = builder.Build();
JobRunner runner = host.Services.GetRequiredService<JobRunner>();
await runner.RunAsync();
1回だけ仕事をして終わるアプリでも、設定・ログ・DIが欲しければGeneric Hostは十分使えます。BackgroundServiceの作成は必須ではありません。
常駐処理:BackgroundServiceの使い方
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddScoped<PollingJob>();
builder.Services.AddHostedService<PollingWorker>();
using IHost host = builder.Build();
await host.RunAsync();
internal sealed class PollingWorker(
IServiceScopeFactory scopeFactory,
ILogger<PollingWorker> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using PeriodicTimer timer = new(TimeSpan.FromSeconds(30));
while (await timer.WaitForNextTickAsync(stoppingToken))
{
using IServiceScope scope = scopeFactory.CreateScope();
PollingJob job = scope.ServiceProvider.GetRequiredService<PollingJob>();
await job.RunAsync(stoppingToken);
}
}
}
重要ポイント:
BackgroundServiceには既定のスコープがない- scopedサービス(
DbContextなど)を使う場合はIServiceScopeFactoryで明示的にスコープを作成 - 仕事が終わったら
IHostApplicationLifetime.StopApplication()でホストに停止を通知
向いているケース
- 設定・ログ・DIを使うコンソールアプリ
- キュー消費者、ポーラー、ウォッチドッグなどの常駐worker
- Ctrl+CやSIGTERMで後片付けしたい長時間実行アプリ
- 将来的にWindows Serviceやコンテナ常駐へ成長する可能性があるアプリ
- ASP.NET Coreと同じ流儀に揃えたい
向かない/過剰なケース
- 引数を1回読んで1回出力して終わる小さなツール
- 数十分だけ使う検証コード
- ライブラリプロジェクト
- 設定を1つ読むだけでDIやログやライフタイム管理が不要な場合
はまりやすいポイント
- Generic HostをDIコンテナだけだと思う — 実際は起動・停止・設定・ログを含む土台
- 新規アプリなのに
Host.CreateDefaultBuilderから始める — 新規ならCreateApplicationBuilderのほうが素直 BackgroundServiceにscopedサービスを直接注入する — 明示的にスコープを作成する- 1回だけの処理なのに
BackgroundServiceで囲う — 普通のサービスクラスを解決して実行すれば十分 Environment.Exitで強制終了する —StopApplication()のほうがきれいに止まる- Windows Serviceでカレントディレクトリ前提にする —
IHostEnvironment.ContentRootPathを基準にする - 定期実行にcallbackタイマーを雑に入れる —
asyncベースならPeriodicTimerのほうが安全
まとめ
Generic Hostは重たい儀式のための道具ではありません。設定・ログ・依存関係・起動・終了が増えてきたら、それらをまとめて管理するための土台です。
- Generic HostはDIだけでなく、設定・ログ・停止処理・hosted serviceを含む
- 新規非Webアプリなら
Host.CreateApplicationBuilder(args)が素直 - 短命ジョブなら
BackgroundServiceなしでも使える - 常駐処理なら
BackgroundService+ hostのライフタイム管理が効く - scopedサービスは明示的にスコープを作成する
- ASP.NET Coreの
WebApplicationBuilderも同じ流れの上にある
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
デスクトップアプリにGeneric Hostを導入する
WPF や WinForms の常駐アプリで、起動・停止・例外処理・定期処理が UI に染み出してきたら読みたい記事。Generic Host と BackgroundService を導入して責務を整理し、graceful shutdown まで設計に組み込む考え方を、最...
.NET Native AOT 入門【JIT/ReadyToRun/trimmingとの違い】
Native AOT が JIT や ReadyToRun、trimming、source generator とどう違うのかを整理し、起動と配布で得られる利点と、リフレクションや WPF まわりで注意したい制約を実務目線でまとめた入門記事です。
.NETの定期実行タイマー3種を使い分ける
PeriodicTimer・System.Threading.Timer・DispatcherTimer の違いと、async 処理・ThreadPool callback・WPF の UI 更新でどう使い分けるかを、判断表とコード例で整理した .NET 定期実行の入門記事です。
FileSystemWatcherの安全な使い方
FileSystemWatcher のイベントは完了通知ではないという前提に立ち、取りこぼし、重複通知、完了判定の落とし穴を整理し、再スキャン要求への畳み込み、原子的 claim、idempotency までの設計指針をまとめます。
C# async/await 実践ガイド【Task.Run/ConfigureAwaitの使い分け】
C# の async/await を実務で迷わず使うための判断表をまとめた記事です。I/O 待ちと CPU 計算の分け方、Task.Run と ConfigureAwait の使い分け、fire-and-forget 置き換え、レビュー観点まで一気に整理できます。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
Generic Host / アプリ設計テーマ
Generic Host、DI、BackgroundService、構成設計を整理するトピックです。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
Windowsアプリ開発
業務アプリ、装置連携、通信ツールなどの Windows ソフト開発を支援します。
技術相談・設計レビュー
改修方針、設計レビュー、既存資産の扱いを整理するための技術相談です。