4

由於ServiceLocatorAwareInterface可能爲removed from the AbstractController in ZF3,因此依賴關係應該通過構造函數或setter方法傳遞。Zend Framework 2 MVC應用程序中的依賴關係管理

考慮到這一點,考慮用戶或站點控制器的用例,其中包括註冊,激活帳戶,登錄,註銷等操作。至少需要一個UserService和2個表單。添加幾個相關的操作(遠程驗證,帳戶鏈接等),最終得到4或5個表單。

通過構造函數傳遞所有這些依賴關係至多是凌亂的,更重要的是,每個動作通常只需要1個表單。

您認爲以下哪種技術更好?爲什麼?

  1. 爲每個動作創建單獨的控制器,以便每個控制器只需要一個表單(除了服務)。例如RegistrationController,LoginController,LinkAccountController等。

    • 你最終得到了很多控制器。
  2. 在控制器的工廠中,根據請求的動作提供不同的形式。

    • 控制器的建設變得依賴於這家工廠,更具體的要求環境(路由等),你可以直接構造控制器(用於測試或別的什麼),但你需要確保依賴關係可用,如果不是,則會拋出異常。
  3. 使用事件管理器,在需要表單時觸發控制器中的事件,並讓事件處理程序根據需求提供相關性。

    • 該技術被描述爲here
    • 然後,您的控制器將依賴於EventManager,而不是ServiceLocator,這可能不會更好。
  4. 將FormElementManager傳遞給控制器​​,並從中請求表單。

    • 沒有比SL本身更可能。
  5. 直接在控制器內部構造表單。

    • 這是如何影響可測性的?
    • 同樣的問題將適用於處理具有多個服務(而不是表單)的控制器。
  6. 其他?

參見:

+3

我不會發布這作爲一個答案,但: 1)我沒有看到許多控制器是一個問題。 2)永遠不會這樣做。工廠是廢料邏輯。不要試圖徹底改變它。 3)maaaaagic - 嘗試調試! 4)表單元素管理器_IS_ a ServiceLocator 5)不,我們離開了那個 – Ocramius

回答

0

第一,服務定位將不會被刪除。也許只是ServiceLocatorAwareInterface。

正如你所說,傳遞FormElementManager是一個解決方案,它確實比傳遞服務定位器更好。我個人使用越來越多的插件管理器,它們是解決這類問題的好方法。插件管理器與服務定位器不同,因爲它允許只檢索一種類型的對象(窗體,水合器,輸入過濾器...)。當然,由於父服務定位器被注入到插件管理器中,所以有些人會從插件管理器中獲取服務定位器的技巧(這就是爲什麼我想在ZF3中刪除插件管理器中的服務定位器,特定的工廠,其父定位器通過注入,但它會使工廠接口複雜一些:/ ...)。

這樣,將控制器拆分成更小的控制器,應該使代碼更清潔。如果你正確地注入認證服務(或者將認證服務注入到用戶服務或類似的東西中),它會顯着減少對控制器的依賴關係。

+0

對不起,我的意思是ServiceLocatorAwareInterface,我已經更新了這個問題。 WRT認證,我有兩個適配器,一個用於本地,一個用於遠程認證,所以我需要兩個服務,因此也需要兩個控制器。 – darkangel

0

您需要考慮您嘗試解決域問題。在用戶域中,有很多形式。因此,將它們聚合到一個存儲庫中。表單存儲庫將與其他倉庫一樣傳遞到用戶服務中,如實體存儲庫。然後用戶服務將被傳遞到控制器。

// UserService 
public function getForm($name, $id = null) 
{ 
    $form = $this->formRepository->find($name); 
    if ($id !== null) { 
     $entity = $this->entityRepository->find($id); 
     $form->bind($entity); 
    } 
    return $form; 
} 
+0

表單存儲庫與FormElementManager有何不同? (通過限制可以返回哪些形式?)另外,什麼是表單存儲庫,以及它如何實例化或訪問表單?我以前沒有見過這種模式。 – darkangel

+0

@darkangel我也經常使用這種模式。表單存儲庫與表單元素管理器不同,因爲您可以創建自己的「User \ Repository \ FormRepository」類,該類僅實例化2或3個表單。這爲您的表單存儲庫提供了一個非常具體的範圍,併爲您的控制器提供了靈活性。 BTW。通常我把「倉庫」稱爲「表單工廠」,所以你會得到一個'User \ Factory \ FormFactory'或其他東西。 –