Container de Injeção de Dependência para JavaScript (Node.js): Awilix

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Container de Injeção de Dependência para JavaScript (Node.js): Awilix



No desenvolvimento moderno com Node.js, manter a pureza da arquitetura e a testabilidade do código é criticamente importante. Um dos padrões-chave que ajudam nisso é a Injeção de Dependência (DI). Para implementar eficazmente esse padrão no ambiente JavaScript, foram criadas bibliotecas especializadas — os containers de Injeção de Dependência. Neste artigo, examinaremos detalhadamente uma das bibliotecas mais populares e leves — Awilix.



O que é Injeção de Dependência e para que serve um container?



Na abordagem tradicional, o próprio objeto cria suas dependências (por exemplo, usando o operador new). Isso leva a um forte acoplamento do código, dificultando os testes e a modificação. O padrão Injeção de Dependência propõe passar (injetar) as dependências externamente. O container automatiza esse processo: ele sabe como criar objetos e suas dependências, e fornece instâncias prontas sob demanda.



Awilix: um container DI leve e poderoso



Awilix é uma biblioteca para JavaScript (Node.js) que implementa o padrão Inversão de Controle (IoC) usando um container. Ela foi escrita do zero para Node.js, suporta resolução assíncrona de dependências, vários estilos de registro (classes, fábricas, valores) e descoberta automática de dependências através do construtor.



Principais funcionalidades:

  • Injeção automática: O container analisa os parâmetros do construtor ou função e injeta automaticamente as dependências necessárias.
  • Suporte a assincronismo: As dependências podem ser assíncronas (por exemplo, conexão com banco de dados), e o container aguarda corretamente sua resolução.
  • Diferentes modos de registro: Você pode registrar classes (asClass), funções fábrica (asFunction) ou valores prontos (asValue).
  • Escopos (Scopes): São suportados diferentes ciclos de vida dos objetos (singleton, transient, scoped).
  • Modularidade: O container pode ser facilmente dividido em módulos e as dependências registradas em diferentes partes da aplicação.


Instalação e uso básico



A instalação do Awilix é feita via npm:



npm install awilix


Vamos considerar um exemplo simples. Suponha que temos um serviço para trabalhar com usuários, que depende de um logger e de um repositório.



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

// 1. Definindo as dependênciasclass Logger { log(message) { console.log(`[LOG]: ${message}`); }}

class UserRepository { constructor({ logger }) { this.logger = logger; }

findById(id) { this.logger.log(`Buscando usuário com ID: ${id}`); return { id, name: 'John Doe' }; }}

class UserService { constructor({ userRepository, logger }) { this.userRepository = userRepository; this.logger = logger; }

getUser(id) { this.logger.log('Requisição no UserService'); return this.userRepository.findById(id); }}

// 2. Criando o container e registrando as dependênciasconst container = createContainer();

container.register({ logger: asClass(Logger).singleton(), userRepository: asClass(UserRepository).singleton(), userService: asClass(UserService).singleton()});

// 3. Usando o container para obter o serviçoconst userService = container.resolve('userService');const user = userService.getUser(1);console.log(user);// Saída:// [LOG]: Requisição no UserService// [LOG]: Buscando usuário com ID: 1// { id: 1, name: 'John Doe' }<

Recommendations