Container de Injeção de Dependência para PHP: o que é e para que serve?
O container de Injeção de Dependência (DI) é uma ferramenta poderosa para gerenciar dependências em aplicações PHP. Ele automatiza o processo de criação de objetos e injeção de suas dependências, tornando o código mais modular, testável e sustentável. Neste artigo, vamos detalhar o conceito de DI, explorar bibliotecas populares e mostrar exemplos de uso.
Conceitos básicos
- Dependência (Dependency) — qualquer objeto externo que uma classe precisa para funcionar (por exemplo, conexão com banco de dados, logger, serviço de e-mail).
- Injeção de Dependência (Dependency Injection) — padrão onde as dependências são passadas para o objeto externamente, em vez de serem criadas dentro dele.
- Container — um repositório centralizado que sabe como criar todas as dependências e gerenciar seu ciclo de vida.
Por que usar um container DI?
Sem um container DI, os desenvolvedores frequentemente criam dependências diretamente nos construtores das classes, o que leva a um código fortemente acoplado. Isso dificulta os testes, a substituição de componentes e a reutilização de código. O container DI resolve esses problemas:
- Resolução automática de dependências (autowiring).
- Configuração centralizada de todos os serviços.
- Gerenciamento do ciclo de vida dos objetos (singleton, factory, prototype).
- Simplificação de testes unitários.
Containers DI populares para PHP
1. PHP-DI (php-di.org)
Um dos containers mais populares e poderosos. Suporta autowiring, anotações, configuração PHP e integração com frameworks populares.
// Exemplo de uso do PHP-DIuse DI\\ContainerBuilder;
class Mailer { public function send($to, $message) { echo "E-mail enviado para {$to}: {$message}"; }}
class UserService { private $mailer; public function __construct(Mailer $mailer) { $this->mailer = $mailer; } public function registerUser($email) { // Lógica de registro $this->mailer->send($email, 'Bem-vindo!'); }}
$builder = new ContainerBuilder();$container = $builder->build();
$userService = $container->get(UserService::class);$userService->registerUser('user@example.com');2. Symfony DependencyInjection (symfony.com/doc/current/components/dependency_injection.html)
Componente do Symfony, usado no framework homônimo. Destaca-se pelo alto desempenho e extensibilidade. A configuração pode ser em YAML, XML ou PHP.
// Exemplo de configuração services.ymlservices: App\\Service\\Mailer: class: App\\Service\\Mailer App\\Service\\UserService: class: App\\Service\\UserService arguments: - '@App\\Service\\Mailer'3. Laravel Service Container (laravel.com/docs/container)
Container embutido do Laravel, usado por padrão. Suporta resolução automática, vinculação de interfaces a implementações e vinculação contextual.
// Exemplo no Laraveluse App\\Services\\PaymentGateway;use App\\Contracts\\PaymentInterface;
// Vinculação de interface à implementação$this->app->bind(PaymentInterface::class, PaymentGateway::class);
// Resolução automáticaclass OrderController { public function __construct( private PaymentInterface $payment ) {} public function process() { $this->payment->charge(100); }}Como funciona um container DI: análise detalhada
Vamos examinar o mecanismo de funcionamento usando o PHP-DI como exemplo. O container usa reflexão do PHP para analisar os construtores das classes e criar automaticamente as dependências. O processo é o seguinte:
Também na biblioteca
Recommendations