Skip to content

Контроль времени жизни

В InferDI есть три вида времени жизни:

ВидСозданиеКешОчистка
singletonодин раз на контейнер-владелецконтейнер-владелецда
scopedодин раз на scopescopeда
transientпри каждом resolveникогданет

Правило жизненного цикла

Singleton не может напрямую зависеть от scoped или transient сервиса. Singleton создаётся один раз и разделяется между всеми запросами, поэтому если он захватит scoped-значение - контекст текущего запроса, пользователя или транзакцию - состояние одного запроса незаметно протечёт во все остальные. InferDI делает такую связь невыразимой в системе типов, а не оставляет её на code review.

ts
new Container()
  .registerClass('request', RequestContext, [], 'scoped')
  .registerClass('users', UserService, ['request'], 'singleton')

Такую регистрацию отклонит TypeScript. В strict mode та же форма будет отклонена runtime-защитой, если каст обойдёт систему типов.

Строгий режим

strict: true включен по умолчанию. Он ловит:

  • нарушения singleton-to-scoped и singleton-to-transient через касты
  • утечки из фабрик, которые захватили внешний контейнер
  • синхронные singleton-циклы
  • синхронные transient-циклы
  • неправильное использование динамических ключей, обходящее статическую проверку
ts
const root = new Container({ strict: true })

Быстрый режим

Используйте strict: false только после того, как тесты доказывают форму графа:

ts
const root = new Container({ strict: false })

Быстрый режим убирает runtime-учёт циклов и времени жизни из пути resolve. Он не меняет контракт на уровне типов, но не защищает от нечестных кастов, захваченных внешних контейнеров и циклов.

Рекомендуемый процесс: разрабатывать и тестировать в strict mode, а затем переключать только критичные к производительности production-графы после аудита.