模仿laravel,使用反射来实现自动依赖注入
2019-08-15 本文已影响0人
lifefruity
在看laravel源码的时候,在Container.php中有个build的方法,主要就是用了反射来进行实例化
参照它的写法,自己写了一个小例子
这里写的比较简单,就是一个依赖参数,正常应该普通参数也要放进去
类似在person类里的address
public function __construct(Bag weight, $address){}
<?php
/*
* 目的:通过反射,自动找依赖注入的类。
* 在实例的时候,里面的$bag, $book自动去查找,并且实例化
* */
class Book{
public function name(){
return '语文书';
}
}
class Bag{
public $book;
public function __construct(Book $book){
$this->book = $book;
}
public function name(){
return "学生书包里有什么书呢 - ". $this->book->name()."\n";
}
}
class Person{
public $oneBag;
public function __construct(Bag $bag){
$this->oneBag = $bag;
}
public function goToSchool(){
echo $this->oneBag->name();
}
}
class Ioc{
public static function getInstance($className){
$obj = new ReflectionClass($className);
$args = self::getParams($className);
// $args = [new Bag(new Book)];//一开始调试,直接这个赋值,这是对的
return $obj->newInstanceArgs($args);
}
public static function getParams($className){
$paramArr = [];
$reflector = new ReflectionClass($className);
$construct = $reflector->getConstructor();
if($construct){//判断是否有 __construct 方法
$needParams = $construct->getParameters();
foreach($needParams as $needParam){
//如果传入的参数是个依赖注入的参数的话,而不是一个普通的参数。
//像这里Bag实例化的时候又需要Book
if($needParam->getClass()){
//如果__construct里的又是依赖注入,继续
$sonParam = self::getParams($needParam->getName());
$paramArr[] = (new ReflectionClass($needParam->getName()))
->newInstanceArgs($sonParam);
}
}
}
return $paramArr;
}
}
$student = Ioc::getInstance('Person');
$student->goToSchool();
//打印 学生书包里有什么书呢 - 语文书