对动态创建对象的依赖关系注入


Dependency injection on dynamically created objects

我正在使用反射来测试一个类是否具有特定的父类,然后返回它的实例。

if (class_exists($classname)) {
     $cmd_class = new 'ReflectionClass($classname);
     if($cmd_class->isSubClassOf(self::$base_cmd)) {
         return $cmd_class->newInstance();
     }
} 

我希望能够对这些实例化的对象进行单元测试,但我不知道在这种情况下是否有任何方法可以使用依赖注入。我的想法是使用工厂来获取依赖项。工厂模式是最佳选择吗?

My thought was to use factories to get dependencies

通过使用此方法,您仍然不知道类具有哪些依赖项。我建议更进一步,并使用反射API解决依赖关系。

您实际上可以键入提示构造函数参数,并且反射 API 完全能够读取类型提示。

这是一个非常基本的例子:

<?php
class Email {
    public function send()
    {
        echo "Sending E-Mail";
    }
}
class ClassWithDependency {
    protected $email;
    public function __construct( Email $email )
    {
        $this->email = $email;
    }
    public function sendEmail()
    {
        $this->email->send();
    }
}

$class = new 'ReflectionClass('ClassWithDependency');
// Let's get all the constructor parameters
$reflectionParameters = $class->getConstructor()->getParameters();
$dependencies = [];
foreach( $reflectionParameters AS $param )
{
    // We instantiate the dependent class
    // and push it to the $dependencies array 
    $dependencies[] = $param->getClass()->newInstance();
}
// The last step is to construct our base object
// and pass in the dependencies array
$instance = $class->newInstanceArgs($dependencies);
$instance->sendEmail(); //Output: Sending E-Mail

当然,您需要自己进行错误检查(例如,如果没有构造函数参数的Typehint)。此外,此示例不处理嵌套依赖项。但是你应该得到基本的想法。

更进一步,您甚至可以组装一个小的 DI 容器,您可以在其中配置要为某些类型提示注入的实例。