O que é um Container de Injeção de Dependência para TypeScript?
Injeção de Dependência (DI) é um padrão de projeto no qual um objeto recebe suas dependências externamente, em vez de criá-las por conta própria. O container DI é uma ferramenta que gerencia a criação e injeção dessas dependências automaticamente. Em TypeScript, graças à tipagem estática, os containers DI são especialmente eficazes: eles garantem segurança de tipos e simplificam os testes.
A principal função do container é vincular interfaces às suas implementações concretas e resolver cadeias de dependências. Isso permite escrever código fracamente acoplado e modular, fácil de manter e expandir.
Por que usar um container DI em TypeScript?
- Redução do acoplamento do código — as classes não dependem de implementações concretas, apenas de abstrações (interfaces).
- Simplificação dos testes — as dependências são facilmente substituídas por mocks ou stubs.
- Gerenciamento do ciclo de vida — o container pode criar singletons, objetos transitórios ou objetos com escopo definido.
- Resolução automática de dependências — o container constrói a árvore de dependências, poupando o desenvolvedor da construção manual de objetos.
Containers DI populares para TypeScript
Vamos analisar duas bibliotecas mais comuns: InversifyJS e TSyringe. Ambas suportam TypeScript, mas possuem abordagens diferentes.
1. InversifyJS
InversifyJS é um poderoso container IoC com decoradores. Ele exige a declaração explícita das dependências através dos decoradores @injectable() e @inject(). É adequado para projetos grandes com arquitetura bem definida.
Instalação
npm install inversify reflect-metadata --saveNo arquivo tsconfig.json, certifique-se de incluir:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true }}Exemplo de uso
import { Container, injectable, inject } from "inversify";import "reflect-metadata";
// Definimos a interface e o símbolo para vinculaçãointerface ILogger { log(message: string): void;}const TYPES = { ILogger: Symbol.for("ILogger"), IUserService: Symbol.for("IUserService"),};
// Implementação do logger@injectable()class ConsoleLogger implements ILogger { log(message: string): void { console.log(`[LOG]: ${message}`); }}
// Serviço que depende do logger@injectable()class UserService { constructor(@inject(TYPES.ILogger) private logger: ILogger) {}
createUser(name: string): void { this.logger.log(`Usuário ${name} criado`); }}
// Configuração do containerconst 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 é um container DI leve da Microsoft. Ele usa decoradores e resolução automática através do construtor. É ideal para projetos médios e pequenos.
Instalação
npm install tsyringe reflect-metadata --saveA configuração do tsconfig.json é semelhante à do InversifyJS.
Exemplo de uso
import { container, injectable, singleton } from "tsyringe";import "reflect-metadata";
// Registramos a classe como singleton@singleton()class DatabaseConnection { connect(): void { console.log("Conexão com o BD estabelecida"); }}
// Classe com injeção automática de dependência@injectable()class UserRepository { constructor(private db: DatabaseConnection) {}
save(user Também na biblioteca
toml++ para C++: guia completo com exemplos práticos
Configuração de aplicações Kotlin: bibliotecas, abordagens e ferramentas
Geração de PDF em PHP: melhores bibliotecas e exemplos de código
Autorização e Autenticação em Kotlin: JWT, Spring Security e Ktor
Trabalho com imagens em PHP: redimensionamento e corte (resize, crop)