2014-07-03 33 views
0

所以我想建立一个依赖注入容器,可以在使用类型提示的依赖关系中自动连线。当依赖关系具有自己的依赖关系时会出现问题。换句话说,我希望我的依赖容器能够处理无限嵌套的依赖关系。PHP的自动线依赖

例如自动布线这个类很容易:

class Bar 
{ 
    public function __construct(Foobar $foobar) 
    { 
     $this->foobar = $foobar; 
    } 

} 

class foo 
{ 
    public function __construct(Bar $bar) 
    { 
     $this->bar = $bar; 
    } 
} 

现在,如果酒吧也有一个依赖我必须以某种方式注入foobar的吧,然后才酒吧为foo。

class foobar 
{ 

} 

class Bar 
{ 
    public function __construct(Foobar $foobar) 
    { 
     $this->foobar = $foobar; 
    } 

} 


class foo 
{ 
    public function __construct(Bar $bar) 
    { 
     $this->bar = $bar; 
    } 
} 

我已经搜索了几个小时,没有找到任何有用的东西,也许有人可以指向我正确的方向。

+0

递归肯定会有用。但是,真的,为什么你不看容器的来源,可以做到这一点,看看它是如何完成的? – Jon

回答

0

你需要两样东西来实现这一点:递归和Reflection

这里是一个工作示例:

function instantiate($class_name) { 
    $reflection = new ReflectionClass($class_name); 
    $constructor = $reflection->getConstructor(); 

    // If there is no constructor in class, return object as is 
    if(!$constructor) return $reflection->newInstance(); 

    $dependencies = []; 

    $params = $constructor->getParameters(); 
    foreach ($params as $param) { 
     // Check for type hints in constructor 
     $paramType = $param->getClass(); 
     if($paramType) { 
      // If there are type hints, call this very function 
      // again (recursion) in order to fetch dependency 
      $dependencies[] = instantiate($paramType->name); 
     } 
    } 

    // Return object (resp. dependency if in recursion loop) 
    // while also passing required constructor parameters 
    return $reflection->newInstanceArgs($dependencies); 
} 

$foo = instantiate('foo'); 

如果你的print_r($ foo的),你会再看看,对象 '富'包含它的依赖关系。

foo Object 
(
    [bar] => Bar Object 
     (
      [foobar] => foobar Object 
       (
       ) 

     ) 

)