Адаптеры фреймворков
Адаптеры InferDI связывают типизированный контейнер с жизненным циклом фреймворка. HTTP-адаптеры создают отдельный скоуп на запрос и предоставляют его через объект запроса или контекста. React-адаптер предоставляет типизированный контекст и может управлять дочерним скоупом на клиенте.
Адаптеры отвечают за создание, доступность и освобождение скоупов. Благодаря этому @inferdi/inferdi остаётся без зависимостей и фреймворковой логики. В ядро не добавляются декораторы, сканирование контроллеров и маршрутов или внедрение зависимостей в параметры обработчиков. Интеграция использует жизненный цикл фреймворка.
Пакеты
| Пакет | Фреймворк | Где хранится скоуп | Режим без скоупа запроса |
|---|---|---|---|
@inferdi/fastify | Fastify v5 | request.di | да |
@inferdi/hono | Hono v4 | c.var.di | нет |
@inferdi/koa | Koa v3 | ctx.state.di | нет |
@inferdi/express | Express 5 | req.di | нет |
@inferdi/elysia | Elysia v1 | context.di | да |
@inferdi/react | React 19 | Контекст React | внешний Provider |
React использует жизненный цикл компонента. Внешний Provider никогда не освобождает переданный контейнер. Управляемый ScopeProvider создаёт дочерний скоуп после фиксации изменений React (commit) и всегда освобождает его. Подробнее на странице React-адаптера.
Общий контракт жизненного цикла
В режиме со скоупами каждый HTTP-адаптер выполняет следующие шаги для каждого запроса:
- Создать: в начале запроса адаптер создаёт скоуп через
createScope(по умолчаниюroot.createScope()). - Предоставить доступ: сохраняет скоуп в объекте запроса или контекста фреймворка. Hono, Koa, Express и Elysia делают это до настройки. Fastify заполняет
request.diпосле успешной настройки, а при её ошибке временно предоставляет скоуп на время очистки. Хуки очистки видят скоуп в публичном поле, но обработчики ошибок не получают частично подготовленный скоуп. - Настроить:
setupScopeвыполняет дополнительную инициализацию до запуска обработчиков. Настройка может быть асинхронной. - Обработать запрос: обработчики маршрутов и ошибок получают сервисы из скоупа.
- Освободить ресурсы: в подходящий момент жизненного цикла адаптер вызывает
disposeScope(по умолчаниюscope.dispose()), если владение не передано приложению.
Общие опции
| Опция | По умолчанию | Назначение |
|---|---|---|
container | обязательна | Корневой контейнер, доступный приложению. Адаптеры его не очищают, кроме Fastify при явно включённом disposeRootOnClose. |
createScope | root.createScope() | Создаёт скоуп запроса. Объявленные данные запроса передавайте здесь. Может быть асинхронным. |
setupScope | нет | Выполняет дополнительную инициализацию до обработчиков. Может быть асинхронным. |
disposeScope | scope.dispose() | Позволяет задать синхронное или асинхронное освобождение ресурсов. |
autoDispose | true | false или предикат, вернувший false, передаёт освобождение ресурсов вашему коду. |
onDisposeError | стандартный обработчик адаптера | Принимает ошибки очистки скоупа запроса: Fastify request.log.error, Koa ctx.app.emit('error'), остальные console.error. |
skipInferdiDispose(...) | - | Передаёт приложению ответственность за скоуп одного запроса, например для потокового ответа или фоновой задачи. |
Правила ошибок и владения
- При ошибке настройки передаётся только исходная ошибка. Если
setupScopeвыбрасывает исключение, адаптер пытается освободить частично подготовленный скоуп и передаёт дальше исходное исключение. Ошибка этой очистки поступает вonDisposeErrorили стандартный обработчик и не добавляется к исходной. - Ошибка запроса не отменяет очистку. Маркер
skipInferdiDisposeпропускает очистку только при успешном ответе. При ошибке скоуп освобождается независимо от маркера, если это допускаетautoDispose. Исключение: middleware Express не видит обработанную ошибку маршрута, поэтому при отключённой автоочистке скоуп остаётся во владении приложения. autoDispose: falseиskipInferdiDisposeпередают владение приложению. Ваш код должен сам освободить скоуп в подходящий момент жизненного цикла.- Ошибки очистки после отправки ответа поступают в обработчик ошибок. Они не передаются клиенту и не меняют уже отправленный ответ.
Важные различия
| Адаптер | Разница |
|---|---|
| Fastify | Освобождает скоуп в onResponse; очистка при обрыве соединения идёт через onRequestAbort; освобождение корневого контейнера включается через disposeRootOnClose. |
| Hono | Освобождает скоуп после await next(); функции потоковой передачи могут вернуть ответ до завершения потока, поэтому часто нужен skipInferdiDispose. |
| Koa | Ждёт события объекта ответа Node.js finish или close, поэтому обычные тела потоковых ответов не требуют отключения автоочистки. |
| Express | Не может увидеть перехваченную ошибку маршрута из middleware с обратными вызовами; упавший запрос с пропущенной автоочисткой остаётся во владении приложения. |
| Elysia | Очистка привязана к onAfterResponse; если этот хук не вызывается, адаптер не может освободить ресурсы внутри скоупа. |
