Contenedor de Inyección de Dependencias para JavaScript (Node.js) — Awilix

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

Contenedor de Inyección de Dependencias para JavaScript (Node.js) — Awilix



En el desarrollo moderno con Node.js, la limpieza de la arquitectura y la testabilidad del código pasan a primer plano. Una de las herramientas clave para lograr estos objetivos es la inyección de dependencias (Dependency Injection, DI). La biblioteca Awilix proporciona un contenedor DI potente, eficiente y flexible para JavaScript y TypeScript, ideal para aplicaciones de servidor con Node.js. En este artículo, analizaremos en detalle cómo usar Awilix para gestionar dependencias, mejorar la modularidad y simplificar las pruebas.



¿Qué es la Inyección de Dependencias y para qué sirve un contenedor?



La Inyección de Dependencias es un patrón de diseño en el que un objeto recibe sus dependencias desde el exterior, en lugar de crearlas él mismo. Esto implementa el principio de Inversión de Control (IoC). Un contenedor es una herramienta que automatiza el proceso de creación y suministro de estas dependencias. En lugar de crear manualmente instancias de clases y pasarlas entre sí, usted describe las reglas de construcción en el contenedor, y él mismo resuelve todas las cadenas de dependencias.



Principales ventajas de usar un contenedor DI:

  • Reducción del acoplamiento del código: Los módulos dependen de abstracciones, no de implementaciones concretas.
  • Simplificación de las pruebas: Es fácil reemplazar servicios reales por mocks durante las pruebas unitarias.
  • Gestión centralizada: Toda la configuración de dependencias se encuentra en un solo lugar, lo que facilita la refactorización.
  • Gestión del ciclo de vida: El contenedor puede controlar cuánto tiempo vive un objeto: una única instancia para toda la aplicación (singleton) o una nueva en cada solicitud.


Instalación de Awilix



Para empezar, instale la biblioteca a través de npm:

npm install awilix


Awilix no tiene dependencias externas y funciona tanto con módulos CommonJS como ESM.



Conceptos principales de Awilix



Awilix se basa en varios conceptos clave:

  • Container (contenedor): El objeto principal que almacena y proporciona las dependencias.
  • Registration (registro): El proceso de vincular un nombre (token) con una fábrica, clase o valor.
  • Resolver (resolvedor): Un objeto que determina cómo crear u obtener la dependencia. Por ejemplo, asClass(), asFunction(), asValue().
  • Lifetime (tiempo de vida): Indica cuántas veces se creará el objeto: ScopedLifeTime (una vez por ámbito), SingletonLifeTime (una vez durante toda la ejecución) o TransientLifeTime (una nueva cada vez).


Ejemplo de uso: servicio para trabajar con usuarios



Consideremos un ejemplo sencillo. Supongamos que tenemos una base de datos, un repositorio de usuarios y un servicio para la lógica de negocio.



1. Definimos las clases

// database.jsclass Database {    constructor() {        this.connection = 'Connected to DB';    }    query(sql) {        return `Result for: ${sql}`;    }}

// userRepository.jsclass UserRepository { constructor({ database }) { this.db = database; } findById(id) { return this.db.query(`SELECT * FROM users WHERE id = ${id}`); }}

// userService.jsclass UserService { constructor({ userRepository }) { this.repo = userRepository; } getUser(id) { return this.repo.findById(id); }}


Observe los constructores: reciben un objeto con las dependencias. Esta es una práctica estándar para Awilix.



2. Configuración del contenedor

const { createContainer, asClass, asValue, Lifetime } = require('awilix');

const container = createContainer();

// Registramos la

Recommendations