Zend framework2 为实例“UserService”找到LazyServiceLoader的循环依赖项`

Zend framework2 为实例“UserService”找到LazyServiceLoader的循环依赖项`,zend-framework2,circular-dependency,zend-servicemanager,Zend Framework2,Circular Dependency,Zend Servicemanager,在Zend框架2中 我有一个控制器类UserController UserController依赖于UserService UserService依赖于UserChangedListener UserChangedListener依赖于SomeOtherClass SomeOtherClass依赖于UserService 因此这里我的UserController和SomeOtherClass依赖于UserService 我得到一个错误: 例如,找到LazyServiceLoader的循环依赖

在Zend框架2中

我有一个控制器类
UserController

  • UserController
    依赖于
    UserService
  • UserService
    依赖于
    UserChangedListener
  • UserChangedListener
    依赖于
    SomeOtherClass
  • SomeOtherClass
    依赖于
    UserService
因此这里我的
UserController
SomeOtherClass
依赖于
UserService

我得到一个错误:

例如,找到LazyServiceLoader的循环依赖项
UserService

当我在
UserChangedListener

我有

“zendframework/zend servicemanager”:“^2.7.5 | | ^3.0.3”

UserControllerFactory.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);
    }

}
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);
    }
}
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);
    }
}
class SomeOtherClassFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $rootLocator = $serviceLocator->getServiceLocator();

        return new SomeOtherClass(
            $rootLocator->get(UserService::class)
        );
    }
}
UserServiceFactory.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);
    }

}
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);
    }
}
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);
    }
}
class SomeOtherClassFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $rootLocator = $serviceLocator->getServiceLocator();

        return new SomeOtherClass(
            $rootLocator->get(UserService::class)
        );
    }
}
UserChangedListenerFactory.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);
    }

}
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);
    }
}
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);
    }
}
class SomeOtherClassFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $rootLocator = $serviceLocator->getServiceLocator();

        return new SomeOtherClass(
            $rootLocator->get(UserService::class)
        );
    }
}
SomeOtherClassFactory.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);
    }

}
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);
    }
}
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);
    }
}
class SomeOtherClassFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $rootLocator = $serviceLocator->getServiceLocator();

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

看起来您与
UserService
有合法的循环依赖关系。错误消息告诉您,如果没有
UserService
,则无法创建
UserService

通过
\uu-construct
方法使用依赖项注入的良好实践确实带来了这个问题。通过这样做,ZF2将eager将一个非常大的对象图加载到内存中,当您有大量具有复杂嵌套关系的相关“服务”时,您必然会有循环依赖关系

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);
    }

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

  • UserService
    依赖于
    SomeOtherClass
    UserChangedListener
  • SomeOtherClass
    依赖于
    UserService
因此,基本上对于创建
UserService
您需要首先创建
SomeOtherClass
实例,但是对于创建它,您需要已经创建
UserService
实例

我不确定您的体系结构,但根据类名,在
UserService
中附加
UserChangedListener
似乎有点错误。
可能
UserService
应该只触发事件,而不应该知道有关此事件的侦听器的任何信息。但是,这只是一个想法,为了得到好的答案,您需要进一步解释这种依赖关系。

这是一个古老的响应,但请记住,使用
onBootstrap()
将在每个请求上创建UserService和UserChangedListener!不只是在需要的时候!