Контроль времени жизни
В InferDI есть три вида времени жизни:
| Вид | Создание | Кеш | Очистка |
|---|---|---|---|
singleton | один раз на контейнер-владелец | контейнер-владелец | да |
scoped | один раз на scope | scope | да |
transient | при каждом resolve | никогда | нет |
Правило жизненного цикла
Singleton не может напрямую зависеть от scoped или transient сервиса. Singleton создаётся один раз и разделяется между всеми запросами, поэтому если он захватит scoped-значение - контекст текущего запроса, пользователя или транзакцию - состояние одного запроса незаметно протечёт во все остальные. InferDI делает такую связь невыразимой в системе типов, а не оставляет её на code review.
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-циклы
- неправильное использование динамических ключей, обходящее статическую проверку
const root = new Container({ strict: true })Быстрый режим
Используйте strict: false только после того, как тесты доказывают форму графа:
const root = new Container({ strict: false })Быстрый режим убирает runtime-учёт циклов и времени жизни из пути resolve. Он не меняет контракт на уровне типов, но не защищает от нечестных кастов, захваченных внешних контейнеров и циклов.
Рекомендуемый процесс: разрабатывать и тестировать в strict mode, а затем переключать только критичные к производительности production-графы после аудита.
