PHP7 Dependency Injection

This commit is contained in:
Dominik Liebler
2016-09-23 10:12:59 +02:00
parent 1f9348d9a8
commit e6c67c5da5
12 changed files with 694 additions and 643 deletions

View File

@ -1,19 +0,0 @@
<?php
namespace DesignPatterns\Structural\DependencyInjection;
/**
* class AbstractConfig.
*/
abstract class AbstractConfig
{
/**
* @var Storage of data
*/
protected $storage;
public function __construct($storage)
{
$this->storage = $storage;
}
}

View File

@ -1,39 +0,0 @@
<?php
namespace DesignPatterns\Structural\DependencyInjection;
/**
* class ArrayConfig.
*
* uses array as data source
*/
class ArrayConfig extends AbstractConfig implements Parameters
{
/**
* Get parameter.
*
* @param string|int $key
* @param null $default
*
* @return mixed
*/
public function get($key, $default = null)
{
if (isset($this->storage[$key])) {
return $this->storage[$key];
}
return $default;
}
/**
* Set parameter.
*
* @param string|int $key
* @param mixed $value
*/
public function set($key, $value)
{
$this->storage[$key] = $value;
}
}

View File

@ -1,47 +0,0 @@
<?php
namespace DesignPatterns\Structural\DependencyInjection;
class Connection
{
/**
* @var Configuration
*/
protected $configuration;
/**
* @var Currently connected host
*/
protected $host;
/**
* @param Parameters $config
*/
public function __construct(Parameters $config)
{
$this->configuration = $config;
}
/**
* connection using the injected config.
*/
public function connect()
{
$host = $this->configuration->get('host');
// connection to host, authentication etc...
//if connected
$this->host = $host;
}
/*
* Get currently connected host
*
* @return string
*/
public function getHost()
{
return $this->host;
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace DesignPatterns\Structural\DependencyInjection;
class DatabaseConfiguration
{
/**
* @var string
*/
private $host;
/**
* @var int
*/
private $port;
/**
* @var string
*/
private $username;
/**
* @var string
*/
private $password;
public function __construct(string $host, int $port, string $username, string $password)
{
$this->host = $host;
$this->port = $port;
$this->username = $username;
$this->password = $password;
}
public function getHost(): string
{
return $this->host;
}
public function getPort(): int
{
return $this->port;
}
public function getUsername(): string
{
return $this->username;
}
public function getPassword(): string
{
return $this->password;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace DesignPatterns\Structural\DependencyInjection;
class DatabaseConnection
{
/**
* @var DatabaseConfiguration
*/
private $configuration;
/**
* @param DatabaseConfiguration $config
*/
public function __construct(DatabaseConfiguration $config)
{
$this->configuration = $config;
}
public function getDsn(): string
{
// this is just for the sake of demonstration, not a real DSN
// notice that only the injected config is used here, so there is
// a real separation of concerns here
return sprintf(
'%s:%s@%s:%d',
$this->configuration->getUsername(),
$this->configuration->getPassword(),
$this->configuration->getHost(),
$this->configuration->getPort()
);
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace DesignPatterns\Structural\DependencyInjection;
/**
* Parameters interface.
*/
interface Parameters
{
/**
* Get parameter.
*
* @param string|int $key
*
* @return mixed
*/
public function get($key);
/**
* Set parameter.
*
* @param string|int $key
* @param mixed $value
*/
public function set($key, $value);
}

View File

@ -10,17 +10,10 @@ testable, maintainable and extendable code.
Usage Usage
----- -----
Configuration gets injected and ``Connection`` will get all that it DatabaseConfiguration gets injected and ``DatabaseConnection`` will get all that it
needs from ``$config``. Without DI, the configuration would be created needs from ``$config``. Without DI, the configuration would be created
directly in ``Connection``, which is not very good for testing and directly in ``DatabaseConnection``, which is not very good for testing and
extending ``Connection``. extending it.
Notice we are following Inversion of control principle in ``Connection``
by asking ``$config`` to implement ``Parameters`` interface. This
decouples our components. We don't care where the source of information
comes from, we only care that ``$config`` has certain methods to
retrieve that information. Read more about Inversion of control
`here <http://en.wikipedia.org/wiki/Inversion_of_control>`__.
Examples Examples
-------- --------
@ -45,27 +38,15 @@ Code
You can also find these code on `GitHub`_ You can also find these code on `GitHub`_
AbstractConfig.php DatabaseConfiguration.php
.. literalinclude:: AbstractConfig.php .. literalinclude:: DatabaseConfiguration.php
:language: php :language: php
:linenos: :linenos:
Parameters.php DatabaseConnection.php
.. literalinclude:: Parameters.php .. literalinclude:: DatabaseConnection.php
:language: php
:linenos:
ArrayConfig.php
.. literalinclude:: ArrayConfig.php
:language: php
:linenos:
Connection.php
.. literalinclude:: Connection.php
:language: php :language: php
:linenos: :linenos:
@ -78,11 +59,5 @@ Tests/DependencyInjectionTest.php
:language: php :language: php
:linenos: :linenos:
Tests/config.php
.. literalinclude:: Tests/config.php
:language: php
:linenos:
.. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/DependencyInjection .. _`GitHub`: https://github.com/domnikl/DesignPatternsPHP/tree/master/Structural/DependencyInjection
.. __: http://en.wikipedia.org/wiki/Dependency_injection .. __: http://en.wikipedia.org/wiki/Dependency_injection

View File

@ -2,24 +2,16 @@
namespace DesignPatterns\Structural\DependencyInjection\Tests; namespace DesignPatterns\Structural\DependencyInjection\Tests;
use DesignPatterns\Structural\DependencyInjection\ArrayConfig; use DesignPatterns\Structural\DependencyInjection\DatabaseConfiguration;
use DesignPatterns\Structural\DependencyInjection\Connection; use DesignPatterns\Structural\DependencyInjection\DatabaseConnection;
class DependencyInjectionTest extends \PHPUnit_Framework_TestCase class DependencyInjectionTest extends \PHPUnit_Framework_TestCase
{ {
protected $config;
protected $source;
public function setUp()
{
$this->source = include 'config.php';
$this->config = new ArrayConfig($this->source);
}
public function testDependencyInjection() public function testDependencyInjection()
{ {
$connection = new Connection($this->config); $config = new DatabaseConfiguration('localhost', 3306, 'domnikl', '1234');
$connection->connect(); $connection = new DatabaseConnection($config);
$this->assertEquals($this->source['host'], $connection->getHost());
$this->assertEquals('domnikl:1234@localhost:3306', $connection->getDsn());
} }
} }

View File

@ -1,3 +0,0 @@
<?php
return array('host' => 'github.com');

View File

@ -1,37 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Diagram> <Diagram>
<ID>PHP</ID> <ID>PHP</ID>
<OriginalElement>\DesignPatterns\Structural\DependencyInjection\AbstractConfig</OriginalElement> <OriginalElement>\DesignPatterns\Structural\DependencyInjection\DatabaseConfiguration</OriginalElement>
<nodes> <nodes>
<node x="0.0" y="230.0">\DesignPatterns\Structural\DependencyInjection\Connection</node> <node x="0.0" y="251.0">\DesignPatterns\Structural\DependencyInjection\DatabaseConnection</node>
<node x="51.0" y="118.0">\DesignPatterns\Structural\DependencyInjection\ArrayConfig</node> <node x="0.0" y="0.0">\DesignPatterns\Structural\DependencyInjection\DatabaseConfiguration</node>
<node x="0.0" y="0.5">\DesignPatterns\Structural\DependencyInjection\Parameters</node>
<node x="137.0" y="0.0">\DesignPatterns\Structural\DependencyInjection\AbstractConfig</node>
</nodes> </nodes>
<notes /> <notes />
<edges> <edges />
<edge source="\DesignPatterns\Structural\DependencyInjection\ArrayConfig" target="\DesignPatterns\Structural\DependencyInjection\AbstractConfig"> <settings layout="Hierarchic Group" zoom="1.0" x="88.5" y="51.5" />
<point x="39.5" y="-33.5" /> <SelectedNodes />
<point x="169.5" y="93.0" />
<point x="201.5" y="93.0" />
<point x="0.0" y="34.0" />
</edge>
<edge source="\DesignPatterns\Structural\DependencyInjection\ArrayConfig" target="\DesignPatterns\Structural\DependencyInjection\Parameters">
<point x="-39.5" y="-33.5" />
<point x="90.5" y="93.0" />
<point x="58.5" y="93.0" />
<point x="0.0" y="33.5" />
</edge>
</edges>
<settings layout="Hierarchic Group" zoom="1.0" x="133.0" y="179.5" />
<SelectedNodes>
<node>\DesignPatterns\Structural\DependencyInjection\AbstractConfig</node>
</SelectedNodes>
<Categories> <Categories>
<Category>Fields</Category>
<Category>Constants</Category>
<Category>Constructors</Category>
<Category>Methods</Category> <Category>Methods</Category>
<Category>Constants</Category>
<Category>Fields</Category>
</Categories> </Categories>
<VISIBILITY>private</VISIBILITY> <VISIBILITY>private</VISIBILITY>
</Diagram> </Diagram>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 100 KiB