2.6. Dependency Injection
2.6.1. Scopo
Implementare un’architettura con basso accoppiamento affinchè il codice sia meglio testabile, manutenibile ed estensibile.
2.6.2. Utilizzo
DatabaseConfiguration
è iniettata e DatabaseConnexion
otterrà tutto quello di cui necessita da $config
. Senza DI, la configurazione sarebbe stata creata direttamente dentro DatabaseConnexion
la quale non sarebbe stata facile da testare ed estendere.
2.6.3. Esempi
L’ORM Doctrine2 utilizza questo pattern per la configurazione che è iniettata nell’oggetto
Connection
. Per il testing, si può facilmente creare un oggetto mock di configurazione iniettandolo nell’oggettoConnection
.Molti framework possiedono già dei contenitori che usano DI per creare oggetti tramite configurazioni sottoforma di array e iniettarle quando necessario (ad esempio i Controller)
2.6.4. Diagramma UML
2.6.5. Codice
Potete trovare questo codice anche su 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. Test
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}