Skip to content

ライフタイム

InferDI には 3 つのライフタイムがあります:

種類生成タイミングキャッシュ先コンテナによる破棄
singleton所有コンテナごとに 1 回所有コンテナあり
scoped子スコープごとに 1 回子スコープあり
transient解決のたびにキャッシュしないなし

scoped キーは createScope() が返した子コンテナから解決してください。デフォルトのチェック付き契約は、ルートコンテナからの解決を拒否します。

ライフタイムのルール

シングルトンは scoped または transient なサービスに直接依存することはできません。シングルトンは 1 回だけ生成され、すべてのリクエストで共有されます。そのため、スコープドな値 — 現在のリクエストのコンテキスト、ユーザー、トランザクション — をキャプチャしてしまうと、その 1 つのリクエストの状態が他のすべてのリクエストへ静かに漏れ出します。InferDI は、このようなケースをコードレビューに委ねるのではなく、型システム上で表現不可能にします。

ts
import { 
Container
} from '@inferdi/inferdi'
class
RequestContext
{
readonly
requestId
= 'req-1'
} class
UserService
{
constructor(readonly
request
:
RequestContext
) {}
} new
Container
()
.
registerClass
('request',
RequestContext
, [], 'scoped')
.
registerClass
('users',
UserService
, ['request'], 'singleton')

どのランタイム契約でも、この登録は TypeScript によって拒否されます。デフォルトのチェック付き契約では、キャストが型システムを回避した場合でも、同じ形がランタイムで拒否されます。

宣言したスコープ入力は scoped 依存として扱われます。request、認証コンテキスト、tenant、job payload を読む利用者は scoped または transient で登録してください。singleton 利用者はコンパイル時に拒否されます。詳しくはスコープ入力を参照してください。

これらのランタイムチェックを行うかどうかはコンテナ契約で決まります。デフォルト契約と fast 契約の正確な動作はコンテナオプションを 参照してください。