Injeção de Dependência em JavaScript: guia completo para iniciantes

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

Introdução: O que é Injeção de Dependência e para que serve?

\n\n

Imagine que você está montando um computador. Em vez de comprar um monobloco pronto, você escolhe separadamente o processador, a placa de vídeo, a memória RAM e os conecta à placa-mãe. Se quiser atualizar a placa de vídeo, não precisará trocar o computador inteiro — basta substituir um componente. Injeção de Dependência (DI) na programação funciona pelo mesmo princípio.

\n\n

Injeção de Dependência (Dependency Injection) é um padrão de projeto no qual um objeto recebe suas dependências externamente, em vez de criá-las por conta própria. No contexto de JavaScript e Node.js, isso significa que uma classe ou função não cria instâncias de outras classes internamente, mas as recebe através do construtor ou parâmetros.

\n\n

Essa abordagem faz parte do princípio da Inversão de Dependências (Dependency Inversion Principle) do SOLID e torna o código mais flexível, testável e sustentável. Neste artigo, vamos explorar a DI com exemplos práticos para desenvolvedores iniciantes.

\n\n

O problema: acoplamento rígido do código

\n\n

Vamos considerar uma situação típica em uma aplicação Node.js. Suponha que temos um serviço para envio de notificações por e-mail:

\n\n
// Sem Injeção de Dependência\nclass EmailService {\n  sendEmail(to, subject, body) {\n    console.log(`Enviando e-mail para ${to}: ${subject}`);\n    // lógica real de envio\n  }\n}\n\nclass UserService {\n  constructor() {\n    this.emailService = new EmailService(); // ❌ Acoplamento rígido\n  }\n\n  registerUser(email) {\n    // Lógica de registro do usuário\n    this.emailService.sendEmail(email, 'Bem-vindo!', '...');\n  }\n}\n\nconst userService = new UserService();\nuserService.registerUser('user@example.com');\n
\n\n

Qual é o problema? A classe UserService está rigidamente acoplada à implementação específica de EmailService. Se você quiser:

\n
    \n
  • Substituir o envio de e-mail pelo envio de SMS
  • \n
  • Adicionar registro (log) de todas as mensagens enviadas
  • \n
  • Testar o UserService sem realmente enviar e-mails
  • \n
\n\n

Você terá que reescrever o código de UserService. Isso viola o princípio aberto/fechado (Open/Closed Principle).

\n\n

Solução: injeção de dependências através do construtor

\n\n

A primeira e mais simples forma de injeção de dependências é passá-las através do construtor da classe. Vamos reescrever nosso exemplo:

\n\n
// Com Injeção de Dependência\nclass EmailService {\n  sendEmail(to, subject, body) {\n    console.log(`Enviando e-mail para ${to}: ${subject}`);\n  }\n}\n\nclass SmsService {\n  sendSms(phone, message) {\n    console.log(`Enviando SMS para ${phone}: ${message}`);\n  }\n}\n\nclass UserService {\n  constructor(notificationService) {\n    this.notificationService = notificationService; // ✅ Injeção de dependência\n  }\n\n  registerUser(contact, isPhone = false) {\n    // Lógica de registro\n    if (isPhone) {\n      this.notificationService.sendSms(contact, 'Bem-vindo!');\n    } else {\n      this.notificationService.sendEmail(contact, 'Bem-vindo!', '...');\n    }\n  }\n}\n\n// Uso\nconst emailService = new EmailService();\nconst userServiceWithEmail = new UserService(emailService);\nuserServiceWithEmail.registerUser('user@example.com');\n\nconst smsService = new SmsService();\nconst userServiceWithSms = new UserService(smsService);\nuserServiceWithSms.registerUser('+1234567890', true);\n
\n\n

Agora, UserService não sabe qual serviço específico está sendo usado — e-mail ou SMS. Ele simplesmente chama o método sendEmail ou sendSms do objeto recebido. Isso é chamado de inversão de dependências: o módulo de alto nível não depende do módulo de baixo nível; ambos dependem de uma abstração.

\n\n

Vantagens dessa abordagem:

\n
    \n
  • Flexibilidade: fácil de substituir

Blogs

Book Recommendations