Contenedor de Inyección de Dependencias para JavaScript (Node.js): Awilix
En el desarrollo moderno con Node.js, mantener la limpieza de la arquitectura y la capacidad de prueba del código es críticamente importante. Uno de los patrones clave que ayudan en esto es la Inyección de Dependencias (DI). Para implementar eficazmente este patrón en el entorno JavaScript, se han creado bibliotecas especializadas: los contenedores de Inyección de Dependencias. En este artículo, analizaremos en detalle una de las bibliotecas más populares y ligeras: Awilix.
¿Qué es la Inyección de Dependencias y para qué sirve un contenedor?
En el enfoque tradicional, un objeto crea sus propias dependencias (por ejemplo, usando el operador new). Esto genera un fuerte acoplamiento en el código, lo que dificulta las pruebas y la modificación. El patrón de Inyección de Dependencias propone pasar (inyectar) las dependencias desde el exterior. El contenedor automatiza este proceso: sabe cómo crear objetos y sus dependencias, y proporciona instancias listas para usar cuando se solicitan.
Awilix: un contenedor DI ligero y potente
Awilix es una biblioteca para JavaScript (Node.js) que implementa el patrón Inversión de Control (IoC) utilizando un contenedor. Está escrita desde cero para Node.js, admite la resolución asíncrona de dependencias, varios estilos de registro (clases, fábricas, valores) y la detección automática de dependencias a través del constructor.
Características principales:
- Inyección automática: El contenedor analiza los parámetros del constructor o la función e inyecta automáticamente las dependencias necesarias.
- Soporte para asincronía: Las dependencias pueden ser asíncronas (por ejemplo, una conexión a una base de datos) y el contenedor espera correctamente a que se resuelvan.
- Diferentes modos de registro: Puede registrar clases (
asClass), funciones de fábrica (asFunction) o valores ya creados (asValue). - Ámbitos (Scopes): Se admiten diferentes ciclos de vida de los objetos (singleton, transient, scoped).
- Modularidad: El contenedor se puede dividir fácilmente en módulos y registrar dependencias en diferentes partes de la aplicación.
Instalación y uso básico
La instalación de Awilix se realiza a través de npm:
npm install awilixVeamos un ejemplo sencillo. Supongamos que tenemos un servicio para trabajar con usuarios, que depende de un logger y un repositorio.
const { createContainer, asClass, asFunction, asValue } = require('awilix');
// 1. Definimos las dependenciasclass Logger { log(message) { console.log(`[LOG]: ${message}`); }}
class UserRepository { constructor({ logger }) { this.logger = logger; }
findById(id) { this.logger.log(`Buscando usuario con ID: ${id}`); return { id, name: 'John Doe' }; }}
class UserService { constructor({ userRepository, logger }) { this.userRepository = userRepository; this.logger = logger; }
getUser(id) { this.logger.log('Solicitud en UserService'); return this.userRepository.findById(id); }}
// 2. Creamos el contenedor y registramos las dependenciasconst container = createContainer();
container.register({ logger: asClass(Logger).singleton(), userRepository: asClass(UserRepository).singleton(), userService: asClass(UserService).singleton()});
// 3. Usamos el contenedor para obtener el servicioconst userService = container.resolve('userService');const user = userService.getUser(1);console.log(user);// Salida:// [LOG]: Solicitud en UserService// [LOG]: Buscando usuario con ID: 1// { id: 1, name: 'John Doe' }< También en la biblioteca
Trabajo con Excel en C# (.NET): bibliotecas EPPlus, ClosedXML y NPOI
Mapster para C# (.NET): guía completa con ejemplos prácticos
Guía completa de cobra/pflag para Go: ejemplos y uso
Serialización de objetos en C# (.NET): guía completa
Planificador de tareas en C# (.NET): Quartz.NET, Hangfire y Coravel