2

在 Zend Framework 2 中,

我有一个控制器类UserController

  • UserController取决于UserService
  • UserService取决于UserChangedListener
  • UserChangedListener取决于SomeOtherClass
  • SomeOtherClass取决于UserService

所以在这里我UserControllerSomeOtherClass都依赖于UserService.

我收到错误:

例如,发现了 LazyServiceLoader 的循环依赖项 UserService

上述错误(即 LazyServiceLoader 的循环依赖)在我注入时SomeOtherClass发生UserChangedListener

我有

"zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3",

用户控制器工厂.php

class UserControllerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $container = $container->getServiceLocator();

        return new UserController(
            $container->get(UserService::class)
        );
    }

    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return $this($serviceLocator, UserController::class);
    }

}

用户服务工厂.php

class UserServiceFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $service = new UserService(
            $container->get(UserRepository::class)
        );

        $eventManager = $service->getEventManager();
        $eventManager->attach($container->get(UserChangedListener::class));

        return $service;
    }

    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return $this($serviceLocator, UserService::class);
    }
}

UserChangedListenerFactory.php

class UserChangedListenerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $container = $container->getServiceLocator();

        return new UserChangedListener(
            $container->get(SomeOtherClass::class)
        );
    }

    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return $this($serviceLocator, UserChangedListener::class);
    }
}

SomeOtherClassFactory.php

class SomeOtherClassFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $rootLocator = $serviceLocator->getServiceLocator();

        return new SomeOtherClass(
            $rootLocator->get(UserService::class)
        );
    }
}
4

2 回答 2

0
  • UserService依赖于SomeOtherClass通过 UserChangedListener
  • SomeOtherClass取决于UserService

所以基本上创建UserService你需要先创建SomeOtherClass实例,但要创建它你需要UserService已经创建实例。

我不确定您的架构,但根据类名,您附加UserChangedListenerUserService. 可能UserService应该只触发事件,并且不应该知道有关此事件的侦听器的任何信息。但同样 - 这只是想法,为了得到好的答案,您需要更多地解释这种依赖关系。

于 2017-06-15T20:51:01.823 回答
0

看起来你有一个合法的循环依赖UserService。错误消息告诉您,如果UserService没有UserService.

这确实是通过__construct方法使用依赖注入的良好实践引入的问题。通过这样做,ZF2 将急切地将一个非常大的对象图加载到内存中,当您有许多具有复杂嵌套关系的相关“服务”时,您必然会有循环依赖。

ZF2 确实提供了延迟服务作为延迟某些对象实例化的解决方案,作为开发人员,您需要决定哪些对象(我建议UserChangedListener)。

或者,要更新您的代码,您可以将侦听器代码的注册移到方法之外UserServiceFactory并移到Module::onBootstrap()方法中。

namespace User;

class Module
{   
    public function onBootstrap(EventInterface $event)
    {
        $serviceManager = $event->getApplication()->getServiceManager();

        // Create the user service first
        $userService = $serviceManager->get(UserService::class);

        $listener = $serviceManager->get(UserChangedListener::class);

        // The create and attach the listener after user service has been created.
        $userService->getEventManager()->attach($listener);
    }

}

如果您使用“聚合”侦听器,这将是必需的。对于简单的事件侦听器,您还可以使用SharedEventManagerwhich 可以防止UserService在上面的示例中加载的开销。

于 2017-06-15T20:48:06.527 回答