在我的Symfony 2.8
项目中,我使用bundle继承覆盖/扩展FOSUserBundle
:自定义包中具有相同路径和名称的文件覆盖FOSUserBundle
中的原始文件。 / p>
虽然这适用于控制器和翻译和视图等资源,但它似乎不适用于服务类。
例如,FOSUserBundle
使用Resources\config\util.xml
来定义fos_user.util.password_updater
服务,以使用Util\PasswordUpdater.php
中定义的类。
简单地将Util\PasswordUpdater.php
添加到继承的包中不起作用。此文件将被忽略,捆绑包仍使用原始版本。
这是服务的缩进行为(因为原始服务定义仍然指向原始文件),或者我做错了什么?
覆盖/扩展服务的正确方法是什么?我找到了information,使用compiler pass
是一般的最佳解决方案。但是,当已经使用bundle继承时,这也是真的吗?
答案 0 :(得分:3)
要覆盖您需要在Bundle中创建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');
}
}
在Bundle文件中注册:
class AppBundle extends FOSUserBundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new OverrideServiceCompilerPass());
}
}
然后将加载您的服务文件。在此文件中,您可以扩展原始服务文件和共享方法,也可以创建全新服务。
答案 1 :(得分:3)
我发现信息,使用编译器传递通常是最好的解决方案。但是,当已经使用bundle继承时,这也是真的吗?
是的,Compiler Pass是覆盖服务定义的最合适的解决方案。它是标准的Symfony DI问题,与bundle继承过程无关。
有时bundle也会在参数中定义类名。在这种情况下,您只需设置这些参数即可覆盖服务。但是这种技术是官方最佳实践not recommended,今天很少使用。