PHP实现IOC依赖注入

<?php

class A
{
    public function doAction($a)
    {
        echo __CLASS__ . ":" . 'hello' . "\n";
        var_dump($a);
    }
}

class B
{
    private $a;

    public function __construct(A $group)
    {
        $this->a = $group;
    }

    public function doAction($a)
    {
        $this->a->doAction($a);
        echo __CLASS__ . ":" . 'hello' . "\n";
    }
}

class C
{
    private $b;

    public function __construct(B $department)
    {
        $this->b = $department;
    }

    public function doAction($a)
    {
        $this->b->doAction($a);
        echo __CLASS__ . ":" . 'hello' . "\n";
    }
}
class Container
{
    private $instances = array();

    public function bind($name, $class)
    {
        $this->instances[$name] = $class;
    }
    public function make($name)
    {
        if (!isset($this->instances[$name])){
            throw new Exception(sprintf("Can not find instance '%s', probably not injected", $name));
        }
        return $this->build($this->instances[$name]);
    }

    public function build($className)
    {
        $reflector = new ReflectionClass($className);

        if (!$reflector->isInstantiable()) {
            throw new Exception("Can't instantiate this.");
        }

        $constructor = $reflector->getConstructor();

        if (is_null($constructor)) {
            return new $className;
        }

        $parameters = $constructor->getParameters();
        $dependencies = $this->getDependencies($parameters);

        return $reflector->newInstanceArgs($dependencies);
    }

    public function getDependencies($parameters)
    {
        $dependencies = [];
        foreach ($parameters as $parameter) {
            $dependency = $parameter->getClass();
            //如果构造函数依赖的是一个类,则解析类的参数
            //否则递归解析类
            if (is_null($dependency)) {
                $dependencies[] = $this->resolveNonClass($parameter);
            } else {
                $dependencies[] = $this->build($dependency->name);
            }
        }
        return $dependencies;
    }

    public function resolveNonClass($parameter)
    {
        if ($parameter->isDefaultValueAvailable()) {
            return $parameter->getDefaultValue();
        }

        throw new Exception('the value:' . $parameter->name . ' miss default value');
    }
}

$di = new Container();
$di->bind('c', 'C');
$company = $di->make('c');
$company->doAction('a');
发布了226 篇原创文章 · 获赞 31 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/why444216978/article/details/104382818