2016-11-14 74 views
2

似乎有兩種方式在Symfony的動態實例化服務:Symfony - 使用服務工廠還是服務配置器更好?

這兩種方法似乎是電流。檢查問題和更改日誌並沒有給我更多的信息,哪些是最常見的或哪種方法被認爲是最佳實踐。

所以,我應該使用服務工廠在服務配置或服務配置了工廠?爲什麼和哪個更近?

非常感謝!

+0

其他幾個人要求其公共接口的一部分的方法的參數,發佈您的特定使用案例的詳細信息。尤其要區分「編譯時」配置和基於請求的「運行時」配置。 – Cerad

回答

0

使用服務工廠在服務配置是在一些特殊情況下,更好的決策:

1)創建服務定義爲老年PHP類,因爲在過去,創建邏輯往往隱藏靜態工廠類 例如內,Doctrine_Core :: getTable()

public static function getTable($componentName) 
{ 
    return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName); 
} 

https://github.com/doctrine/doctrine1/blob/master/lib/Doctrine/Core.php

2)一個使用工廠服務和方法用於檢索服務的特別好的例子是Doctrine存儲庫的 案例。當你需要一個,你通常會注入實體管理器作爲 構造函數的參數,並在以後檢索特定的資源庫:

use Doctrine\ORM\EntityManager; 

class SomeClass 
{ 
    public function __construct(EntityManager $entityManager) 
    { 
     $this->entityManager = $entityManager; 
    } 

    public function doSomething() 
    { 
     $repository = $this->entityManager->getRepository('User'); 
    } 
} 

但是使用工廠服務和方法,你可以直接注入正確的庫本身:

class SomeClass 
{ 
    public function __construct(UserRepository $userRepository) 
    { 
     $this->userRepository = $userRepository; 
    } 
} 

...

<service id="some_service" class="SomeClass"> 
    <argument type="user_repository" /> 
</service> 

...

<service id="user_repository" class="UserRepository" 
    factory-service="entity_manager" factory-method="getRepository"> 
    <argument>User</argument> 
</service> 

通過查看SomeClass的構造函數參數,立即清楚它需要一個 用戶存儲庫,它比SomeClass需要EntityManager的早期示例更具體和更具通信性。除了使類本身更清潔,也會使 它更容易創建一個獨立的對象存儲庫,當你正在編寫單元測試這個 類。而不是創建兩個實體管理器和庫一個模擬的,你只需要 創建一個存儲庫本身。

缺點是(按Matthias ):

我反對靜態工廠方法的工廠類是 靜態代碼是全局代碼,並且該執行該代碼可能有側面 無法隔離的影響(例如在測試場景中)。 此外,這種靜態工廠方法的任何依賴性必須由定義爲靜態的本身,這對隔離也是非常不利的,並且 可以防止您用自己的 代碼替換(部分)創建邏輯。工廠對象(或工廠服務)略好。 然而,需要對他們非常有可能指向某種設計 問題。服務不應該需要工廠,因爲它只會以預定的(確定的)方式創建 一次,並且從此 可以被任何其他對象完全重用。這是 動態有關服務的唯一的東西,應該是那個 是

+0

那麼你真的可以在什麼時候使用服務配置器?基本上,我的服務參數之一是在運行時動態定義的,info通過文件系統「發現」。 http://stackoverflow.com/questions/23156907/how-can-i-dynamically-set-a-parameter-in-symfony2 – Hussard

+0

你能更新與動態服務的代碼原來的問題? –

2

基本上它們不一樣:一個工廠用於創建服務,配置器用於創建後配置它。

當您需要實例化服務(也許注入其他服務或參數)時,請使用標準服務配置文件(即:services.yml)。

當您需要控制服務實例化時使用工廠。

當您需要在創建之後配置您的服務並且希望將服務定義與服務配置分開時使用服務配置器。

+0

您是否真的可以使用服務配置器?基本上,我的服務參數之一是在運行時動態定義的,info通過文件系統「發現」。 http://stackoverflow.com/questions/23156907/how-can-i-dynamically-set-a-parameter-in-symfony2 – Hussard

+0

@Hardard如果你閱讀你鏈接的文檔,你會發現真正的用例 – DonCallisto