2.6. Injeção de dependência (Dependency Injection)
2.6.1. Objetivo
Implementar uma arquitetura menos acoplada com o objetivo de obter um código mais fácil de testar, de melhor manutenibilidade e mais extensível.
2.6.2. Uso
DatabaseConfiguration
é injetado e DatabaseConnection
irá receber tudo o que é necessário de $config
. Sem a Injeção de Dependência, a configuração seria criada diretamente em DatabaseConnection
, o que não é muito bom para testar e extender isto.
2.6.3. Exemplos
O ORM Doctrine 2 usa injeção de dependência, por exemplo, para a configuração que é injetada no objeto
Connection
. Para propósitos de teste, algúem pode facilmente criar um objeto simulado na configuração e injetá-lo no objetoConnection
.muitos frameworks já têm contêineres para ID que criam objetos por meio de um array de configuração e os injetam onde necessário (ou seja, nos Controladores)
2.6.4. Diagrama UML
2.6.5. Código
Você pode também ver este código no GitHub
DatabaseConfiguration.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\DependencyInjection;
6
7class DatabaseConfiguration
8{
9 public function __construct(
10 private string $host,
11 private int $port,
12 private string $username,
13 private string $password
14 ) {
15 }
16
17 public function getHost(): string
18 {
19 return $this->host;
20 }
21
22 public function getPort(): int
23 {
24 return $this->port;
25 }
26
27 public function getUsername(): string
28 {
29 return $this->username;
30 }
31
32 public function getPassword(): string
33 {
34 return $this->password;
35 }
36}
DatabaseConnection.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\DependencyInjection;
6
7class DatabaseConnection
8{
9 public function __construct(private DatabaseConfiguration $configuration)
10 {
11 }
12
13 public function getDsn(): string
14 {
15 // this is just for the sake of demonstration, not a real DSN
16 // notice that only the injected config is used here, so there is
17 // a real separation of concerns here
18
19 return sprintf(
20 '%s:%s@%s:%d',
21 $this->configuration->getUsername(),
22 $this->configuration->getPassword(),
23 $this->configuration->getHost(),
24 $this->configuration->getPort()
25 );
26 }
27}
2.6.6. Teste
Tests/DependencyInjectionTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace DesignPatterns\Structural\DependencyInjection\Tests;
6
7use DesignPatterns\Structural\DependencyInjection\DatabaseConfiguration;
8use DesignPatterns\Structural\DependencyInjection\DatabaseConnection;
9use PHPUnit\Framework\TestCase;
10
11class DependencyInjectionTest extends TestCase
12{
13 public function testDependencyInjection()
14 {
15 $config = new DatabaseConfiguration('localhost', 3306, 'user', '1234');
16 $connection = new DatabaseConnection($config);
17
18 $this->assertSame('user:1234@localhost:3306', $connection->getDsn());
19 }
20}