In Zend Framework 2,
I have a controller class UserController
UserController
is dependent on UserService
UserService
is dependent on UserChangedListener
UserChangedListener
is dependent on SomeOtherClass
SomeOtherClass
is dependent on UserService
So here my UserController
and SomeOtherClass
are dependent on UserService
.
I am getting error :
Circular dependency for LazyServiceLoader was found for instance
UserService
The above error (ie Circular dependency for LazyServiceLoader) occurred when I injected SomeOtherClass
in UserChangedListener
And I have
"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);
}
}
UserServiceFactory.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)
);
}
}
Looks like you have a legitimate circular dependency with UserService
. The error message is telling you that the UserService
cannot be created without the UserService
.
This is really a problem introduced by the good practice of using dependency injection via the __construct
method. By doing so, ZF2 will eager load a very large object graph into memory, when you have lots of related 'services' that have complex nested relationships you are bound to have circular dependencies.
ZF2 does offer Lazy Services as a solution to delay the instantiation of certain objects that as the developer you will need to decide on which ones (I would suggest UserChangedListener
).
Alternatively to update your code, you could move the registration of the listener code outside of the UserServiceFactory
and into the Module::onBootstrap()
method.
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);
}
}
This would be required if you are using the 'aggregate' listeners. For simple event listeners you can also use the SharedEventManager
which would prevent the overhead of loading the UserService
in the above example.
UserService
is dependent on SomeOtherClass
through UserChangedListener
SomeOtherClass
is dependent on UserService
So basically for creation UserService
you need first create SomeOtherClass
instance, but for create it you need UserService
instance to be created already.
I'm not sure about your architecture, but according to class names it looks bit wrong that you attach UserChangedListener
in UserService
. Probably UserService
should only fire events, and shouldn't know anything about listeners for this events. But again - that just idea, and for good answer you need to explain this dependencies bit more.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.