スポンサーリンク

.NETのAddScoped / AddSingleton / AddTransient の違い

ASP.NET Core では、依存性の注入(Dependency Injection)がフレームワークに標準で組み込まれており、AddScoped、AddSingleton、AddTransient を使ってサービスのライフタイムを管理します。

この記事では、それぞれの登録方法がどう異なり、どのような場面で使うべきかを詳しく解説します。

依存性の注入とライフタイムの関係

まず前提として、依存性の注入ではサービスのライフタイム(生成されてから破棄されるまでの期間)を指定することができます。

.NET では次の 3 種類のライフタイムが標準で提供されています。

  • Transient(都度生成)
  • Scoped(スコープごとに 1 回生成)
  • Singleton(アプリケーション全体で 1 回のみ生成)

これらは IServiceCollection にサービスを登録する際に、それぞれ AddTransientAddScopedAddSingleton を使って指定します。

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:アプリ全体で共有するべき重複しない処理に向いている

まとめると上記のような感じになります。