Dev Study
NestJS コース

32. インジェクションスコープ — Singleton / Request / Transient

プロバイダの既定のスコープはシングルトンで、アプリ起動時に一度だけ生成されたインスタンスを全リクエストで共有します。これを変えたいときは @Injectable({ scope: Scope.REQUEST }) のように指定します。Scope.REQUEST はリクエストごとに新しいインスタンスを作り、Scope.TRANSIENT は注入されるたびに新しいインスタンスを作ります。

実務でシングルトン以外を選ぶのは、リクエスト固有の状態(ログインユーザーやリクエスト ID など)をプロバイダ自身に持たせたい場合です。ただし Scope.REQUEST はリクエストごとに生成コストがかかり、それを注入したコントローラやサービスまで連鎖的にリクエストスコープ化されるため、パフォーマンスに影響します。多くの場合は状態を引数で渡すか、既習の @User() のようなデコレータで取り出すほうが軽量です。

下のコードはシングルトン(同一インスタンスを共有)とトランジェント(毎回新規)の違いを、生成カウンタで再現したものです。つまずきポイントは、シングルトンなプロバイダにリクエスト固有の状態を持たせてしまうことで、状態が全リクエストで共有され、別ユーザーの情報が混ざる危険があります。状態を持たせたいときだけスコープを上げる、と覚えましょう。

▶ サンプルコードを実行してみよう(自由に書き換えてOK)

TypeScript
サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗