laravel 依赖注入

<?php
interface Animal{

public function attack();
public function talk();

}

class People implements Animal
{
public $month;
public $hand;
public function __construct(Mouth $mouth,Hand $hand)
{
$this->month = $mouth;
$this->hand = $hand;

}

public function attack()
{
$this->hand->scrap();
}

public function talk()
{
$this->month->say();
}

}

class Mouth{
public function say(){
echo "咿咿呀呀";
}
}
class Hand{
public $finger;
public function __construct(Finger $finger)
{
$this->finger = $finger;
}

public function scrap(){
echo '仍玩具';
}

public function otherFunction(){
$this->finger->eatFinger();
}
}

class Finger{
public function eatFinger(){
echo "吃手指";
}
}


class Container
{
/**
* 容器绑定,用来装提供的实例或者 提供实例的回调函数
* @var array
*/
public $building = [];

/**
* 注册一个绑定到容器
*/
public function bind($abstract, $concrete = null, $shared = false){
if(is_null($concrete)){
$concrete = $abstract;
}

if(!$concrete instanceOf Closure){
$concrete = $this->getClosure($abstract, $concrete);
}

$this->building[$abstract] = compact("concrete", "shared");
}

//注册一个共享的绑定 单例
public function singleton($abstract, $concrete, $shared = true){
$this->bind($abstract, $concrete, $shared);
}

/**
* 默认生成实例的回调闭包
*
* @param $abstract
* @param $concrete
* @return Closure
*/
public 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($concrete, $abstract)){
$object = $this->build($concrete);
}else{
$object = $this->make($concrete);
}

return $object;
}

/**
* 获取绑定的回调函数
*/
public function getConcrete($abstract){

if(! isset($this->building[$abstract])){
return $abstract;
}

return $this->building[$abstract]['concrete'];
}

/**
* 判断 是否 可以创建服务实体
*/
public function isBuildable($concrete, $abstract){

return $concrete === $abstract || $concrete instanceof Closure;
}

/**
* 根据实例具体名称实例具体对象
*/
public function build($concrete){

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

//创建反射对象
$reflector = new ReflectionClass($concrete);//通过反射获取类名

if( ! $reflector->isInstantiable()){
//抛出异常
throw new \Exception('无法实例化');
}

$constructor = $reflector->getConstructor();//获取构造函数
if(is_null($constructor)){
return new $concrete;
}

$dependencies = $constructor->getParameters();//获取构造函数参数
$instance = $this->getDependencies($dependencies);
return $reflector->newInstanceArgs($instance);//将参数注入到对象中

}

//通过反射解决参数依赖
public function getDependencies(array $dependencies){
$results = [];
foreach( $dependencies as $dependency ){
$results[] = is_null($dependency->getClass())
?$this->resolvedNonClass($dependency)
:$this->resolvedClass($dependency);
}

return $results;
}

//解决一个没有类型提示依赖
public function resolvedNonClass(ReflectionParameter $parameter)
{
if($parameter->isDefaultValueAvailable()){
return $parameter->getDefaultValue();
}
throw new \Exception('出错');

}

//通过容器解决依赖
public function resolvedClass(ReflectionParameter $parameter)
{
return $this->make($parameter->getClass()->name);

}

}
//实例化容器类
$container = new Container();
$container->bind('Animal','People');//将需要创建对象的类放到容器中
$people = $container->make('Animal');//创建对象
$people->attack();//调用方法
$people->talk();
posted on 2019-10-19 12:59  paulversion  阅读(416)  评论(0编辑  收藏  举报