Last active
September 13, 2019 01:43
-
-
Save hastinbe/c1657f88c9e1f7fa77681e70819da980 to your computer and use it in GitHub Desktop.
An example of a rudimentary dependency injection container #php #dic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
interface Database {} | |
class Mysql implements Database {} | |
class Postgresql implements Database {} | |
class Container | |
{ | |
protected $bindings = []; | |
public function bind($interface, $concrete) | |
{ | |
$this->bindings[$interface] = $concrete; | |
} | |
protected function resolveDependencies($dependencies) | |
{ | |
$instances = []; | |
foreach ($dependencies as $dependency) { | |
$instances[] = $dependency->getClass() === null | |
? $this->resolvePrimitive($dependency) | |
: $this->resolveClass($dependency); | |
} | |
return $instances; | |
} | |
private function resolvePrimitive($parameter) | |
{ | |
if ($parameter->isDefaultValueAvailable()) { | |
return $parameter->getDefaultValue(); | |
} | |
return null; | |
} | |
private function resolveClass($parameter) | |
{ | |
return $this->make($parameter->getClass()->name); | |
} | |
public function make($interface, $parameters = []) | |
{ | |
if (!isset($this->bindings[$interface])) { | |
throw new Exception('Binding not found'); | |
} | |
return new $this->bindings[$interface](); | |
} | |
public function build($concrete) | |
{ | |
$reflector = new ReflectionClass($concrete); | |
$constructor = $reflector->getConstructor(); | |
if ($constructor === null) { | |
return new $concrete(); | |
} | |
if (!$reflector->isInstantiable()) { | |
return null; | |
} | |
$dependencies = $constructor->getParameters(); | |
$instances = $this->resolveDependencies($dependencies); | |
return $reflector->newInstanceArgs($instances); | |
} | |
} | |
class Application extends Container | |
{ | |
} | |
class Model | |
{ | |
private $db; | |
public function __construct(Database $db) | |
{ | |
$this->db = $db; | |
} | |
public function getDatabase() | |
{ | |
return $this->db; | |
} | |
} | |
$app = new Application(); | |
$app->bind('Database', 'Mysql'); | |
$model = $app->build('Model'); | |
var_dump($model->getDatabase()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment