2016-12-06 50 views
0

在我的Symfony 2.8項目中,我使用包繼承來覆蓋/擴展FOSUserBundle:自定義包中具有相同路徑和名稱的文件覆蓋了FOSUserBundle中的原始文件。Symfony包繼承 - 如何覆蓋/擴展服務類

雖然這適用於控制器和資源(如翻譯和視圖),但它似乎不適用於服務類。

例如,FOSUserBundle使用Resources\config\util.xml來定義fos_user.util.password_updater服務以使用Util\PasswordUpdater.php中定義的類。

簡單地將Util\PasswordUpdater.php添加到繼承的包不起作用。該文件將被忽略,並且該包仍然使用原始版本。

這是服務的縮進行爲(因爲原始服務定義仍然指向原始文件),還是我做錯了什麼?

覆蓋/擴展服務的正確方法是什麼?我發現information,使用compiler pass是最好的解決方案。但是,如果已經使用了bundle繼承,這是否也是真的?

+0

用編譯器傳遞覆蓋服務是最好的解決方案。我認爲服務比控制器和資源更早加載。 – Rawburner

+0

你試過編輯'app/config.service.yml'嗎? – AnthonyB

回答

3

要覆蓋你需要在你的包來創建CompilerPass服務:

<?php 

namespace AppBundle\DependencyInjection\Compiler; 
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 

/** 
* Class OverrideServiceCompilerPass 
* @package Shopmacher\IsaBodyWearBundle\DependencyInjection\Compiler 
*/ 
class OverrideServiceCompilerPass implements CompilerPassInterface 
{ 

    /** 
    * Overwrite project specific services 
    * @param ContainerBuilder $container 
    */ 
    public function process(ContainerBuilder $container) 
    { 
     $defNewService = $container->getDefinition('service.id.you.want.to.override'); 
     $defNewService ->setClass('AppBundle\Service\NewService'); 

    } 
} 

註冊在你的包文件:

class AppBundle extends FOSUserBundle 
{ 
    public function build(ContainerBuilder $container) 
    { 
     parent::build($container); 

     $container->addCompilerPass(new OverrideServiceCompilerPass()); 
    } 
} 

那麼你的服務文件將被載入。在此文件中,您可以擴展原始服務文件和共享方法,也可以創建全新的服務。

+0

謝謝,這工作正常。然而,問題仍然是「編譯器是否也傳遞了正確/正確的解決方案,當已經使用bundle繼承時」我假設答案是肯定的,但是確認將會很棒:-) –

3

我發現信息,使用編譯器pass是一般的最佳解決方案。但是,如果已經使用了bundle繼承,這是否也是真的?

是的,Compiler Pass是覆蓋服務定義的最合適的解決方案。它是標準的Symfony DI問題,與bundle繼承過程無關。

有時候bundle也會在參數中定義類名。在這種情況下,您可以通過設置這些參數來覆蓋服務。但這項技術是由官方最佳做法提供的not recommended,目前很少使用。

+0

感謝您的確認!我明白使用參數來定義服務類不是一個好主意。但是,有沒有辦法覆蓋/替換在第三方包中傳遞給服務的參數? –

+0

更好的方式是使用bundle提供的配置選項(或任何記錄的API)。但顯然不是每一件事都可以配置。 服務覆蓋技術(通過編譯器通過或其他)是像猴子修補,並有一個共同的缺點。第三方軟件包的作者幾乎不會假設他們的代碼將被替換。他們可能會在未來版本中更改內部內容,並且這些更改可能會破壞您的代碼。所以,服務重寫始終是危險的。 – Timurib