Adaptadores de frameworks
Los adaptadores de InferDI conectan tipos exactos de contenedor con los límites del lifecycle del framework. Los adaptadores HTTP crean un request scope y lo exponen en la ubicación nativa. El adaptador de React proporciona un context tipado y también puede poseer un scope secundario creado en el cliente.
Ese es todo el trabajo. Los adaptadores son una fina capa de pegamento del ciclo de vida: el mismo diseño que mantiene a @inferdi/inferdi sin dependencias también mantiene los decoradores, el escaneo de controladores, la inyección de parámetros de handlers y el descubrimiento de rutas fuera del núcleo. Optas por el ciclo de vida de las peticiones de un framework, no por la idea que ese framework tenga de la inyección de dependencias.
Paquetes
| Paquete | Framework | Ubicación del scope | Modo solo raíz |
|---|---|---|---|
@inferdi/fastify | Fastify v5 | request.di | sí |
@inferdi/hono | Hono v4 | c.var.di | no |
@inferdi/koa | Koa v3 | ctx.state.di | no |
@inferdi/express | Express 5 | req.di | no |
@inferdi/elysia | Elysia v1 | context.di | sí |
@inferdi/react | React 19 | React context | Provider externo |
React usa el lifecycle del componente en vez del lifecycle de petición descrito abajo. Su Provider externo nunca libera el contenedor; su managed ScopeProvider crea el scope tras el commit y siempre lo libera. Consulta el adaptador de React.
Contrato común del ciclo de vida
En modo con scope, cada adaptador ejecuta los mismos pasos para cada petición:
- Crea el scope a partir del contenedor raíz (
createScope, por defectoroot.createScope()) cuando comienza la petición. - Expone el scope en la ubicación nativa del framework. Hono, Koa, Express y Elysia lo exponen antes de la configuración. Fastify expone
request.didespués de que la configuración tenga éxito y solo lo expone de forma temporal durante la limpieza de un fallo de configuración. Los hooks de limpieza ven el slot público, mientras que los manejadores de errores nunca reciben un scope a medio construir. - Configura el scope con
setupScopesi hace falta inicialización adicional antes de los handlers. Puede ser asíncrono. - Atiende la petición: los handlers de rutas y los manejadores de errores del framework resuelven servicios desde el scope expuesto.
- Libera el scope en el punto de finalización seguro del framework (
disposeScope, por defectoscope.dispose()), salvo que se haya transferido la propiedad.
Opciones compartidas
| Opción | Por defecto | Propósito |
|---|---|---|
container | requerido | Contenedor raíz expuesto a la aplicación. Los adaptadores nunca lo liberan (excepto el disposeRootOnClose opcional de Fastify). |
createScope | root.createScope() | Construye el scope y recibe aquí las entradas declaradas de la petición. Puede ser asíncrono. |
setupScope | ninguno | Ejecuta inicialización adicional antes de los handlers. Puede ser asíncrono. |
disposeScope | scope.dispose() | Limpieza personalizada. Puede ser síncrona o asíncrona. |
autoDispose | true | false, o un predicado que devuelve false, cede la liberación a tu código. |
onDisposeError | sumidero por adaptador | Recibe los fallos de liberación del scope de petición: Fastify request.log.error, Koa ctx.app.emit('error'), los demás console.error. |
skipInferdiDispose(...) | — | Marca una petición como propiedad de la aplicación para streaming o trabajo en segundo plano. |
Reglas de errores y de propiedad
- Un fallo de configuración expone solo el error original. Si
setupScopelanza una excepción, el adaptador libera el scope a medio construir y vuelve a lanzar ese error. Un fallo de limpieza durante esta operación va aonDisposeError(o al sumidero) y nunca se agrega al error expuesto. - Una petición fallida igualmente se libera.
skipInferdiDisposesuprime la limpieza solo en una respuesta exitosa; una ruta de error libera de todos modos. Express es la excepción: su middleware basado en callbacks no puede observar un error de ruta gestionado, por lo que una petición fallida de Express omitida permanece como propiedad de la aplicación. autoDispose: falseyskipInferdiDisposetransfieren la propiedad. Entonces tu código pasa a ser responsable de liberar el scope en el límite correcto del framework.- Los errores de limpieza después de que se produce una respuesta se enrutan al sumidero y se descartan. La respuesta ya se envió, por lo que un fallo tardío de limpieza nunca podrá corromperla.
Diferencias importantes
| Adaptador | Diferencia |
|---|---|
| Fastify | Libera en onResponse; la limpieza por aborto usa onRequestAbort; la liberación de la raíz puede activarse con disposeRootOnClose. |
| Hono | Libera después de await next(); los helpers de streaming pueden devolver antes de que termine el trabajo del stream, por lo que las rutas de streaming a menudo necesitan skipInferdiDispose. |
| Koa | Espera al finish o close de la respuesta de Node, por lo que los cuerpos de stream normales no necesitan un skip. |
| Express | No puede detectar un error de ruta gestionado aguas abajo desde un middleware basado en callbacks; una petición fallida omitida permanece como propiedad de la aplicación. |
| Elysia | La limpieza está vinculada a onAfterResponse; si ese hook nunca se alcanza, el adaptador no puede liberar los recursos retenidos por el scope. |
