2.6. Dependency Injection

2.6.1. Amaç

Daha iyi test edilebilir, bakım yapılabilir ve genişletilebilir kod elde etmek için gevşek bağlı bir mimari uygulamak.

2.6.2. Kullanım

DatabaseConfiguration gets injected and DatabaseConnection will get all that it needs from $config. Without DI, the configuration would be created directly in DatabaseConnection, which is not very good for testing and extending it.

2.6.3. Örnekler

  • Doctrine2 ORM bağımlılık aktarımını kullanır. Örneğin bir Connection nesnesi, yapılandırma (configuration) nesnesine bağımlanmıştır. Test amacıyla bir yapılandırma yapaylaması (configuration mock) kolayca oluşturulabilir ve Connection nesnesine aktarılabilir.

  • many frameworks already have containers for DI that create objects via a configuration array and inject them where needed (i.e. in Controllers)

2.6.4. UML Diyagramı

Alt DependencyInjection UML Diyagramı

2.6.5. Kod

Bu kodu Github üzerinde de bulabilirsiniz.

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}