Contenedor de Inyección de Dependencias para TypeScript: guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Qué es un contenedor de Inyección de Dependencias para TypeScript?



La Inyección de Dependencias (DI) es un patrón de diseño en el cual un objeto recibe sus dependencias desde el exterior, en lugar de crearlas por sí mismo. Un contenedor DI es una herramienta que gestiona la creación e inyección de estas dependencias de forma automática. En TypeScript, gracias al tipado estático, los contenedores DI son especialmente efectivos: garantizan la seguridad de tipos y simplifican las pruebas.



La tarea principal del contenedor es vincular interfaces con sus implementaciones concretas y resolver las cadenas de dependencias. Esto permite escribir código débilmente acoplado y modular, que sea fácil de mantener y ampliar.



¿Por qué se necesita un contenedor DI en TypeScript?



  • Reducción del acoplamiento del código — las clases no dependen de implementaciones concretas, sino solo de abstracciones (interfaces).
  • Simplificación de las pruebas — las dependencias se reemplazan fácilmente con mocks o stubs.
  • Gestión del ciclo de vida — el contenedor puede crear singletons, objetos transitorios u objetos con un ámbito específico.
  • Resolución automática de dependencias — el contenedor construye el árbol de dependencias por sí mismo, liberando al desarrollador de la construcción manual de objetos.


Contenedores DI populares para TypeScript



Consideremos las dos bibliotecas más comunes: InversifyJS y TSyringe. Ambas son compatibles con TypeScript, pero tienen enfoques diferentes.



1. InversifyJS



InversifyJS es un potente contenedor IoC con decoradores. Requiere la indicación explícita de las dependencias mediante los decoradores @injectable() y @inject(). Es adecuado para proyectos grandes con una arquitectura clara.



Instalación

npm install inversify reflect-metadata --save


En el archivo tsconfig.json, asegúrese de incluir:

{  "compilerOptions": {    "experimentalDecorators": true,    "emitDecoratorMetadata": true  }}


Ejemplo de uso

import { Container, injectable, inject } from "inversify";import "reflect-metadata";

// Definimos la interfaz y el símbolo para el enlaceinterface ILogger { log(message: string): void;}const TYPES = { ILogger: Symbol.for("ILogger"), IUserService: Symbol.for("IUserService"),};

// Implementación del logger@injectable()class ConsoleLogger implements ILogger { log(message: string): void { console.log(`[LOG]: ${message}`); }}

// Servicio que depende del logger@injectable()class UserService { constructor(@inject(TYPES.ILogger) private logger: ILogger) {}

createUser(name: string): void { this.logger.log(`Usuario ${name} creado`); }}

// Configuración del contenedorconst container = new Container();container.bind<ILogger>(TYPES.ILogger).to(ConsoleLogger).inSingletonScope();container.bind<UserService>(TYPES.IUserService).to(UserService);

// Usoconst userService = container.get<UserService>(TYPES.IUserService);userService.createUser("Alexei");


2. TSyringe



TSyringe es un contenedor DI ligero de Microsoft. Utiliza decoradores y resolución automática a través del constructor. Es ideal para proyectos medianos y pequeños.



Instalación

npm install tsyringe reflect-metadata --save


La configuración de tsconfig.json es similar a la de InversifyJS.



Ejemplo de uso

import { container, injectable, singleton } from "tsyringe";import "reflect-metadata";

// Registramos la clase como singleton@singleton()class DatabaseConnection { connect(): void { console.log("Conexión a la BD establecida"); }}

// Clase con inyección automática de dependencia@injectable()class UserRepository { constructor(private db: DatabaseConnection) {}

save(user

Recommendations