Здравейте, продължавам с темата за DI Container. До сега съм направил да зарежда автоматично нормални класове и сингълтони. Сега искам да направя когато има интерфейс, контейнерът да види че има интерфейс, да види кой клас го инплементира и да зареди този клас. Как може да стане това?
Ето как изглежда контейнера в момента.
Ето как изглежда контейнера в момента.
Код:
<?php
namespace application;
class Container {
private static $_instance = NULL;
private function __construct() {
}
/** @return \application\Container */
public static function getInstance() {
if (self::$_instance === NULL) {
self::$_instance = new self();
}
return self::$_instance;
}
public function make($class) {
$reflector = new \ReflectionClass($class);
$staticProperties = $reflector -> getStaticProperties();
if ($staticProperties) {
foreach ($staticProperties as $key => $val) {
if ($key == '_instance' && $val === NULL) {
return $class::getInstance();
}
}
}
if (!$reflector -> isInstantiable()) {
throw new \Exception('This Class ' . $class . ' Is Not Instantiable In: ' . __METHOD__, 500);
}
$constructor = $reflector -> getConstructor();
if (is_null($constructor)) {
return new $class;
}
$parameters = $constructor -> getParameters();
$dependencies = $this -> getDependencies($parameters);
return $reflector -> newInstanceArgs($dependencies);
}
public function getDependencies($parameters) {
$dependencies = array();
foreach ($parameters as $parameter) {
$dependency = $parameter -> getClass();
if (is_null($dependency)) {
$dependencies[] = $this -> makeNoClass($parameter);
}
else {
$dependencies[] = $this -> make($dependency -> getName());
}
}
return $dependencies;
}
public function makeNoClass(ReflectionParameter $parameter) {
if ($parameter -> isDefaultValueAvailable()) {
return $parameter -> getDefaultValue();
}
throw new \Exception('This Parameter ' . $parameter . ' Is Unknown In: ' . __METHOD__, 500);
}
}