首页 文章

Symfony 3.4 . 无法覆盖服务

提问于
浏览
4

我正在尝试覆盖"vendor"部分的某些服务 . 按照本指南https://symfony.com/doc/3.4/bundles/override.html我制作了这段代码

namespace AppBundle\DependencyInjection\Compiler;

use AppBundle\Service\Subscriber;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class OverrideServiceCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('MyOldService');
        $definition->setClass(Subscriber::class); //my new service class
    }
}

在“AppBundle \ Service \ Subscriber”上创建订阅者类并尝试覆盖操作后:

<?php

namespace AppBundle\Service;

class Subscriber
{
   public function the_same_name_of_function_from_vendor()
   {
       dump('I am a new function!');die;
       return new Response('ok');
   }
}

但没有什么是开心的,symfony继续从“供应商”部分调用一个函数 .

如何正确覆盖该功能?

2 回答

  • 4

    您必须在src / AppBundle / AppBundle.php中添加此代码:

    在函数build()中

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

    所有课程:

    class AppBundle extends Bundle
    {
        public function build(ContainerBuilder $container)
        {
            parent::build($container);
    
            $container->addCompilerPass(new OverrideServiceCompilerPass());
        }
    }
    

    https://symfony.com/doc/3.4/service_container/compiler_passes.html

    否则你的compilepass没有加载 .

  • 1

    对于覆盖服务的特定情况,您唯一需要做的就是在bundle(或app folder)services.yml中定义一个新服务,就像这样

    lexik_jwt_authentication.security.guard.jwt_token_authenticator:
           class: SeguridadBundle\DependencyInjection\MyJWTTokenAuthenticator
           arguments: ["@lexik_jwt_authentication.jwt_manager", "@event_dispatcher", "@lexik_jwt_authentication.extractor.chain_extractor"]
    

    当然有一些规则:

    • 服务的名称 must be exactly 与供应商中的名称相同 . 因此,我上面写的那个覆盖了在LexikJWTAuthentication供应商中名为 lexik_jwt_authentication.security.guard.jwt_token_authenticator 的另一个服务 .

    • 指定的类将是具有您自己的实现的类 .

    因此,在覆盖服务时,您需要创建一个与原始名称保持相同名称的新定义,但具有不同的实例化类 . 请注意,对于兼容性问题,实现与原始相同的接口是一个很好的建议,即:遵循与原始服务相同的约定,以保证兼容性 .

    对不起我的英语,我希望它有所帮助

相关问题