> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wyrly.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Lifetimes and scopes

> Wyrly DI における singleton、scoped、transient な依存関係の挙動。

ライフタイムは、解決されたインスタンスがどれだけ長く生きるかを定義します。

適切なライフタイムを選ぶことで、状態の所有関係が明確になり、リクエスト固有の依存関係がユーザーやリクエストをまたいで漏れることを防げます。

## Singleton

`singleton` はステートレスなサービスや、プロセス全体で共有する依存関係に使います。

```ts theme={null}
container.register(LoggerToken, {
  useClass: ConsoleLogger,
  lifetime: "singleton",
});
```

よい候補:

* loggers
* 設定リーダー
* 純粋なポリシー
* ステートレスなマッパー

リクエスト固有の状態を singleton に持たせることは避けてください。

## Scoped

`scoped` は 1 リクエストまたは 1 単位の処理の中で再利用すべき依存関係に使います。

```ts theme={null}
container.register(UserRepositoryToken, {
  useClass: UserRepository,
  lifetime: "scoped",
});
```

よい候補:

* リクエストコンテキスト
* リクエストトランザクションに紐づくリポジトリ
* DataLoader インスタンス
* リクエストローカルなキャッシュ

## Transient

`transient` は、resolve のたびに新しい instance を作るべきときに使います。

```ts theme={null}
container.register(ReportBuilder);
```

Transient は、状態を共有する必要がない、短期間だけ使うオブジェクトに向いています。

## Request scopes

Web フレームワークでは、リクエストが始まるとリクエストスコープが作られ、リクエストが終わると破棄されます。

```ts theme={null}
const scope = container.createScope();

try {
  await handleRequest(scope);
} finally {
  await scope.dispose();
}
```

対応しているフレームワークでは、アダプターがこれを自動で行います。

## 子スコープ（v2.1+）

`scope.createChildScope()` で、1 リクエスト内のネストした単位（GraphQL subscription の operation など）を表現できます。

```ts theme={null}
const requestScope = container.createScope();
const operationScope = requestScope.createChildScope();

try {
  requestScope.resolve(RequestDbToken);
  operationScope.resolve(OperationContextToken);
} finally {
  await operationScope.dispose();
  await requestScope.dispose();
}
```

* **子を先に dispose** しないと親の dispose は `ScopeHasActiveChildrenError` になります。
* 子は親の `set()` 値と scoped インスタンスを参照できます。
* 新しい scoped インスタンスは、resolve したスコープにのみ格納されます。

## Lifetime validation

Wyrly はライフタイムの関係を検証できます。singleton が scoped に**直接または間接的に**依存していないか、
`register()` が `@Injectable` の `deps` / `lifetime` と矛盾していないかを確認します。

テストや CI の一部として検証を実行してください。

```ts theme={null}
const result = container.validate();
```
