InversifyJS: Contenedor IoC para aplicaciones TypeScript

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

InversifyJS: Potente contenedor IoC para TypeScript



InversifyJS es un contenedor IoC (Inversión de Control) ligero pero extremadamente potente para aplicaciones TypeScript y JavaScript. Implementa el patrón Inyección de Dependencias (DI), permitiendo a los desarrolladores crear sistemas débilmente acoplados, testeables y escalables. La biblioteca utiliza activamente las capacidades de TypeScript (decoradores, tipos) para garantizar un tipado estricto y facilidad de desarrollo.



InversifyJS es ideal para aplicaciones de servidor en Node.js, así como para proyectos de cliente con frameworks como Angular, React o Vue. En esta revisión, analizaremos los conceptos clave y mostraremos cómo empezar rápidamente.



Conceptos principales de InversifyJS



Antes de escribir código, es importante entender las tres entidades principales de la biblioteca:



  • Contenedor (Container) — el objeto central que gestiona todas las dependencias. En él se registran las abstracciones y sus implementaciones.
  • Identificadores de Servicio (Service Identifiers) — claves únicas mediante las cuales el contenedor encuentra la implementación adecuada. Pueden ser cadenas, símbolos o clases.
  • Decoradores — @injectable() y @inject() — indican a TypeScript que una clase puede ser inyectada y qué dependencias necesita.


Instalación y configuración



Para empezar, instale InversifyJS y sus dependencias de tipografía:



npm install inversify reflect-metadata --savenpm install --save-dev @types/node


Luego, agregue dos opciones obligatorias en tsconfig.json:



{  "compilerOptions": {    "emitDecoratorMetadata": true,    "experimentalDecorators": true,    "types": ["reflect-metadata"]  }}


Después, importe reflect-metadata en el archivo principal de la aplicación (normalmente index.ts o main.ts):



import "reflect-metadata";


Primer ejemplo: un servicio simple



Creemos una interfaz y su implementación. Observe el decorador @injectable():



// interfaces/IWarrior.tsexport interface IWarrior {    fight(): string;}

// entities/Warrior.tsimport { injectable } from "inversify";

@injectable()export class Warrior implements IWarrior { fight(): string { return "¡El guerrero ataca con espada!"; }}


Ahora registremos esta relación en el contenedor y obtengamos una instancia:



import { Container } from "inversify";import { IWarrior } from "./interfaces/IWarrior";import { Warrior } from "./entities/Warrior";

const container = new Container();

// Registramos la abstracción con su implementacióncontainer.bind<IWarrior>("IWarrior").to(Warrior);

// Obtenemos una instanciaconst warrior = container.get<IWarrior>("IWarrior");console.log(warrior.fight()); // "¡El guerrero ataca con espada!"


Inyección de dependencias a través del constructor



El verdadero poder de la DI se revela cuando una clase depende de otra. Usamos el decorador @inject():



// interfaces/IWeapon.tsexport interface IWeapon {    use(): string;}

// entities/Sword.tsimport { injectable } from "inversify";

@injectable()export class Sword implements IWeapon { use(): string { return "¡Espada en mano!"; }}

// entities/Knight.tsimport { injectable, inject } from "inversify";import { IWarrior } from "../interfaces/IWarrior";import { IWeapon } from "../interfaces/IWeapon";

@injectable()export class Knight implements IWarrior { private _weapon: IWeapon;

constructor(@inject("IWeapon") weapon: IWeapon) { this._weapon = weapon; }

fight(): string { return this._weapon.use() + " ¡El caballero lucha!"; }}


Registr

Recommendations