Zend framework2 为实例“UserService”找到LazyServiceLoader的循环依赖项`
在Zend框架2中 我有一个控制器类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的循环依赖
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!不只是在需要的时候!