Skip to content

Instantly share code, notes, and snippets.

@hastinbe
Last active September 13, 2019 01:43
Show Gist options
  • Save hastinbe/c1657f88c9e1f7fa77681e70819da980 to your computer and use it in GitHub Desktop.
Save hastinbe/c1657f88c9e1f7fa77681e70819da980 to your computer and use it in GitHub Desktop.
An example of a rudimentary dependency injection container #php #dic
<?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