ASP.NET Core では、依存性の注入(Dependency Injection)がフレームワークに標準で組み込まれており、AddScoped、AddSingleton、AddTransient を使ってサービスのライフタイムを管理します。
この記事では、それぞれの登録方法がどう異なり、どのような場面で使うべきかを詳しく解説します。
依存性の注入とライフタイムの関係
まず前提として、依存性の注入ではサービスのライフタイム(生成されてから破棄されるまでの期間)を指定することができます。
.NET では次の 3 種類のライフタイムが標準で提供されています。
- Transient(都度生成)
- Scoped(スコープごとに 1 回生成)
- Singleton(アプリケーション全体で 1 回のみ生成)
これらは IServiceCollection
にサービスを登録する際に、それぞれ AddTransient
、AddScoped
、AddSingleton
を使って指定します。
AddTransient(短命インスタンス)
概要
AddTransient
は、サービスが必要になるたびに新しいインスタンスを生成します。
services.AddTransient<IMyService, MyService>();
特徴
- 毎回新しいインスタンスが注入される
- ステートレスな処理向け
- 軽量で使い捨て可能なオブジェクトに適している
使用例
- ロジックを持つだけのユーティリティクラス
- 計算、変換、検証などの一時的な処理
注意点
- 状態を保持する必要がある場合には不向き
- 複数回呼び出されると毎回コストがかかる
AddScoped(スコープ単位のインスタンス)
概要
AddScoped
は、HTTP リクエスト単位で 1 回インスタンスを生成します。同じリクエスト内では同じインスタンスが再利用されます。
services.AddScoped<IMyService, MyService>();
特徴
- 同一リクエスト中は同じインスタンスを使用
- リクエストスコープに関連する処理に適している
使用例
- データアクセス(例:リポジトリクラス)
- ビジネスロジック層のサービス
- 認証情報など、1リクエスト中で共有すべき状態
注意点
- スコープ外で使用しない(例:シングルトンからスコープ付きサービスを使うのはNG)
AddSingleton(長命インスタンス)
概要
AddSingleton
は、アプリケーションの起動時にインスタンスを 1 回だけ生成し、全体で共有されます。
services.AddSingleton<IMyService, MyService>();
特徴
- 1回生成されるだけなのでパフォーマンスが良い
- グローバルな設定やキャッシュに適している
- メモリ使用量を最小限にしたいときに有効
使用例
- 設定情報を保持するサービス
- キャッシュ管理
- ロギングや監視など、ステートを維持したいユーティリティ
注意点
- コンストラクタにスコープ付きサービスを注入しないこと(スコープのミスマッチによりエラーになる)
ライフタイム比較表
ライフタイム | 生成タイミング | 使い回し範囲 | 主な用途 |
---|---|---|---|
AddTransient | 毎回新規生成 | 使い回しなし | 軽量処理、ユーティリティ |
AddScoped | リクエストごと | 同一リクエスト | ビジネスロジック、リポジトリ |
AddSingleton | 最初の1回だけ | アプリ全体 | 設定、キャッシュ、ロガー |
まとめ
- AddTransient:毎回新しいインスタンスが必要な軽量サービスに適している
- AddScoped:1 リクエスト内で状態を共有する必要があるサービスに最適
- AddSingleton:アプリ全体で共有するべき重複しない処理に向いている
まとめると上記のような感じになります。