2

在Zend框架2,爲LazyServiceLoader環形依賴性被發現例如`UserService`

我有一個控制器類UserController

  • UserController取決於UserService
  • UserService取決於UserChangedListener
  • UserChangedListener依賴於SomeOtherClass
  • SomeOtherClass取決於UserService

所以在這裏我UserControllerSomeOtherClass取決於UserService

我得到錯誤:

爲LazyServiceLoader循環依賴被發現的情況下 UserService

上述錯誤(即用於LazyServiceLoader循環依賴),當我在UserChangedListener

注入 SomeOtherClass發生

而且我有

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

回答

0

看起來你有UserService合法的循環依賴。錯誤消息告訴你,如果沒有UserService,則不能創建UserService

這實際上是通過__construct方法使用依賴注入的良好實踐引入的問題。通過這樣做,ZF2將渴望加載一個非常大的對象圖到內存,當你有很多相關的'服務'具有複雜的嵌套關係,你必須有循環依賴。

ZF2確實提供Lazy Services作爲解決延遲,作爲開發人員,你將需要決定哪些(我建議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的開銷。

0
  • UserService取決於SomeOtherClass通過 UserChangedListener
  • SomeOtherClass取決於UserService

所以基本上創造UserService你需要先創建SomeOtherClass實例,但對於創造它,你需要UserService實例是已經創建。

我不確定你的架構,但根據類名看起來有點不對,你在UserService附上UserChangedListener。 可能UserService應該只會觸發事件,並且不應該瞭解有關此事件的偵聽器的任何信息。但是,再一次 - 這只是想法,對於良好的答案,您需要更多地解釋這種依賴關係。