<?php
class Container
{
protected $bindings = [];
// bind用于绑定或者注册服务
public function bind($abstract, $concrete = null, $shared = false) {
if (! $concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
}
$this->bindings[$abstract] = compact('concrete', 'shared');
}
// 为没提供闭包函数的服务提供一个默认的闭包
protected function getClosure($abstract, $concrete) {
return function ($c) use ($abstract, $concrete) {
$method = ($abstract == $concrete) ? 'build' : 'make';
return $c->$method($concrete);
};
}
// 生成实例
public function make($abstract) {
$concrete = $this->getConcrete($abstract);
if ($this->isBuildable($abstract, $concrete)) {
return $this->build($concrete);
}
return $this->make($concrete);
}
// 生成实例
public function build($concrete) {
if ($concrete instanceof Closure) {
return $concrete($this);
}
$reflection = new ReflectionClass($concrete);
if (!$reflection->isInstantiable()) {
echo $message = 'This class is not instantiable !!!!';
return;
}
$constructor = $reflection->getConstructor();
if (is_null($constructor)) {
return new $concrete;
}
$dependencies = $constructor->getParameters();
$parameters = $this->resolveDependencies($dependencies);
return $reflection->newInstanceArgs($parameters);
}
// 解决参数依赖
protected function resolveDependencies($parameters) {
$dependencies = null;
foreach ($parameters as $parameter) {
$_cls = $parameter->getClass();
if (is_null($_cls)) {
$dependencies[] = null;
} else {
$dependencies[] = $this->make($_cls->name);
}
}
return (array) $dependencies;
}
protected function isBuildable($abstract, $concrete) {
return $abstract == $concrete || $concrete instanceof Closure;
}
protected function getConcrete($abstract) {
if (!isset($this->bindings[$abstract])) {
return $abstract;
}
return $this->bindings[$abstract]['concrete'];
}
}
// test code part
Interface A {
public function test();
}
class B implements A {
public function test(){
echo 'This is b from A';
}
}
class C implements A {
public function __construct($name){
$this->name = $name;
}
public function test(){
echo 'This is c from A';
}
}
class D {
public $obj;
/**
* D constructor.
* @param $obj
*/
public function __construct(A $obj)
{
$this->obj = $obj;
}
public function run() {
$this->obj->test();
}
}
$app = new Container();
$app->bind('A', 'C');
$app->bind('D', 'D');
$d = $app->make('D');
$d->run();
Laravel容器----依赖注入【部分源码】
最新推荐文章于 2024-08-12 09:40:06 发布
770

被折叠的 条评论
为什么被折叠?



