Skip to content

Guards de tiempo de vida

InferDI tiene tres tiempos de vida:

ClaseCreadoCacheado enLiberado por el contenedor
singletonuna vez por contenedor propietariocontenedor propietario
scopeduna vez por scope hijoscope hijo
transienten cada resoluciónnuncano

Con strict: true, resolver una clave scoped desde la raíz lanza Scoped "key" cannot be resolved from the root container. Use createScope(). Resuelve los servicios scoped desde un contenedor hijo devuelto por createScope().

La regla del tiempo de vida

Un singleton no puede depender directamente de un servicio scoped o transient. Un singleton se crea una vez y se comparte en cada petición, así que si captura un valor con scope — el contexto, el usuario o la transacción de la petición actual — el estado de esa única petición se filtra de forma silenciosa hacia todas las demás. InferDI hace que ese caso límite sea inexpresable en el sistema de tipos en lugar de dejarlo a la revisión de código.

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

Ese registro lo rechaza TypeScript. En modo estricto, la misma forma se rechaza en runtime si un cast burla el sistema de tipos.

Modo estricto

strict: true es el valor por defecto. Atrapa:

  • resolución directa de una clave scoped desde el contenedor raíz
  • violaciones de singleton a scoped o de singleton a transient introducidas por casts
  • fugas de factorías que capturan un contenedor externo
  • ciclos síncronos de singletons
  • ciclos síncronos de transitorios
  • mal uso de claves dinámicas que burla la comprobación estática
ts
const root = new Container({ strict: true })

Modo rápido

Usa strict: false solo después de que las pruebas demuestren la forma del grafo:

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

El modo rápido elimina del camino de resolución la contabilidad de ciclos y tiempos de vida en runtime. Los scopes leen directamente el registro raíz inmutable, sin recorrer la cadena de padres, y reflejan los singletons delegados en la caché del scope. Los scopes strict recorren su cadena exacta de padres en cada fallo local, por lo que las mutaciones siguen visibles sin conservar metadatos de búsqueda. La deduplicación por identidad de instancias owned se ejecuta durante el disposal en ambos modos. El modo rápido no cambia el contrato a nivel de tipos, pero tampoco puede defenderse frente a casts deshonestos, contenedores externos capturados o ciclos. También omite el guard de scoped en la raíz, por lo que el código de la aplicación no debe resolver claves scoped desde el contenedor raíz.

Flujo de trabajo recomendado: desarrolla y prueba en modo estricto, registra cada clave de runtime una sola vez mediante una cadena fluent lineal y completa el registro antes de la primera resolución o creación de scope. Cambia únicamente grafos de producción auditados e inmutables y elimina los scopes hijos antes que sus ancestros.