父依赖构造函数的新子项,依赖性不起作用

时间:2014-07-08 10:25:18

标签: php dependency-injection zend-framework2 factory

我遇到了通过工厂实例化的A类问题,B类扩展了A类。

这里有一些示例代码:

class ClassAFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $one= $serviceLocator->get('doctrine.entitymanager.one');
        $two= $serviceLocator->get('doctrine.entitymanager.two');
        $three= $serviceLocator->get('Application\Service\three');
        return new ClassA($one, $two, $three);
    }
}

class ClassA implements ServiceLocatorAwareInterface
{
    use ServiceLocatorAwareTrait;

    private $one;
    private $two;
    private $three;

    public function __construct(ObjectManager $one, ObjectManager $two, Three $three)
    {
        $this->one= $one;
        $this->two= $two;
        $this->three= $three;
    }
}

class ClassB extends ClassA
{
    // Some usefull code
}

如何在不传递依赖性的情况下调用B类,如何检索工厂完成的A类实例:new ClassB(); ?

1 个答案:

答案 0 :(得分:2)

你不能直接这样做。您可以ClassB创建服务工厂,但这涉及代码重复:

class ClassBFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $one   = $serviceLocator->get('doctrine.entitymanager.one');
        $two   = $serviceLocator->get('doctrine.entitymanager.two');
        $three = $serviceLocator->get('Application\Service\three');
        return new ClassB($one, $two, $three);
    }
}

但是,您的班级ClassA(以及ClassB)已经知道了服务定位器,因此您可以延迟加载您的实体管理器;这样,您根本不需要服务工厂:

class ClassA implements ServiceLocatorAwareInterface
{
    use ServiceLocatorAwareTrait;

    private $one;
    private $two;
    private $three;

    private function getOne()
    {
        if (!$this->one) {
            $this->one = $this->getServiceLocator()
                              ->get('doctrine.entitymanager.one');
        }

        return $this->one;
    }

    private function getTwo()
    {
        if (!$this->two) {
            $this->two = $this->getServiceLocator()
                              ->get('doctrine.entitymanager.two');
        }

        return $this->two;
    }

    public function __construct(Three $three)
    {
        $this->three = $three;
    }
}

class ClassB extends ClassA
{
    // Some usefull code
}

只需更新ClassA中的代码,即可通过$this->getOne()& $this->getTwo()代替$this->one& $this->two

之后,您可以访问ClassA& ClassB就像其他人一样:

$a = $serviceLocator->get('Namespace\...\ClassA');
$b = $serviceLocator->get('Namespace\...\ClassB');
相关问题