Laravel框架 之 IoC实现

2018-05-23  本文已影响42人  诺之林

本文的示例代码参考IoC3

目录

Startup

关于IoC基础知识和日常使用 可以参考这两篇文章

Leavel1

vim Level1.php
<?php

class Container {
    protected $bindings = [];

    public function bind($abstract, $concrete = null, $shared = false) {
        $this->bindings[$abstract] = compact('concrete', 'shared');
    }

    public function make($abstract) {
        $concrete = $this->getConcrete($abstract);
        $object = $this->build($concrete);
        return $object;
    }

    public function build($concrete) {
        $reflector = new ReflectionClass($concrete);
        return $reflector->newInstanceArgs();
    }

    protected function getConcrete($abstract) {
        if (isset($this->bindings[$abstract])) {
            return $this->bindings[$abstract]['concrete'];
        }

        return $abstract;
    }
}

class JPAService {
    function __construct() {
        print 'JPAService: __construct';
    }
}

$app = new Container();
$app->bind('service', 'JPAService');
$app->make('service');
php Level1.php
JPAService: __construct

Leavel2

vim Level2.php
<?php

class Container {
    protected $bindings = [];

    public function bind($abstract, $concrete = null, $shared = false) {
        $this->bindings[$abstract] = compact('concrete', 'shared');
    }

    public function make($abstract) {
        $concrete = $this->getConcrete($abstract);
        $object = $this->build($concrete);
        return $object;
    }

    public function build($concrete) {
        // 新增代码
        if ($concrete instanceof Closure) {
            return $concrete($this);
        }

        $reflector = new ReflectionClass($concrete);
        return $reflector->newInstanceArgs();
    }

    protected function getConcrete($abstract) {
        if (isset($this->bindings[$abstract])) {
            return $this->bindings[$abstract]['concrete'];
        }

        return $abstract;
    }
}

class JPAService {
    private $driver;

    function __construct($driver) {
        $this->driver = $driver;
    }
}

$app = new Container();
$app->bind('service', function () {
    return new JPAService('MySQL');
});
$service = $app->make('service');
var_dump($service);
php Level2.php
object(JPAService)#3 (1) {
  ["driver":"JPAService":private]=>
  string(5) "MySQL"
}

Leavel3

vim Level3.php
<?php

class Container {
    protected $bindings = [];

    public function bind($abstract, $concrete = null, $shared = false) {
        $this->bindings[$abstract] = compact('concrete', 'shared');
    }

    public function make($abstract) {
        $concrete = $this->getConcrete($abstract);
        $object = $this->build($concrete);
        return $object;
    }

    public function build($concrete) {
        if ($concrete instanceof Closure) {
            return $concrete($this);
        }

        $reflector = new ReflectionClass($concrete);
        // 新增代码
        $constructor = $reflector->getConstructor();
        $dependencies = $constructor->getParameters();
        $instances = $this->resolveDependencies($dependencies);
        return $reflector->newInstanceArgs($instances);
    }

    protected function getConcrete($abstract) {
        if (isset($this->bindings[$abstract])) {
            return $this->bindings[$abstract]['concrete'];
        }

        return $abstract;
    }

    // 新增代码
    protected function resolveDependencies($parameters) {
        $dependencies = [];
        foreach ($parameters as $parameter) {
            $dependency = $parameter->getClass();
            if (! is_null($dependency)) {
                $dependencies[] = $this->resolveClass($parameter);
            }
        }
        return $dependencies;
    }

    // 新增代码
    protected function resolveClass(ReflectionParameter $parameter) {
        return $this->make($parameter->getClass()->name);
    }
}

class JPAService {
    function __construct() {
        print "JPAService: __construct\n";
    }
}

class Controller {
    private $service;

    function __construct(JPAService $service) {
        $this->service = $service;
    }
}

$app = new Container();
$app->bind('service', 'JPAService');
$app->bind('controller',  'Controller');
$controller = $app->make('controller');
var_dump($controller);
php Level3.php
JPAService: __construct
object(Controller)#5 (1) {
  ["service":"Controller":private]=>
  object(JPAService)#8 (0) {
  }
}

想要了解Laravel IoC的完整实现 可以参考Laravel IoC源码

参考

上一篇下一篇

猜你喜欢

热点阅读