4
votes

I'm trying to override some service from "vendor" section. Following this guide https://symfony.com/doc/3.4/bundles/override.html I made this code

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
    }
}

After I made a Subscriber class at "AppBundle\Service\Subscriber" and tried to override an action:

<?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');
   }
}

But nothing happaned and symfony continues to call a function from "vendor" section.

How can I override the function correctly?

2
Can you verify you have the correct service id to override?JacobW
Try dumping $definition after setclass to see whats thereEakethet

2 Answers

4
votes

You have to add this code in src/AppBundle/AppBundle.php:

In function build()

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

All class:

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

Else your compilerpass is not load.

2
votes

For the specific case of overriding a service the only thing you have to do is define a new service in your bundle( or app folder) services.yml like this

       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"]

There are some rules, of course:

  • The name of the service must be exactly the same it has in the vendor. So, the one I wrote above overrides another service called lexik_jwt_authentication.security.guard.jwt_token_authenticator in theLexikJWTAuthentication vendor.
  • The class specified will be the one with your own implementation.

So, when overriding a service you need to create a new definition that keeps the same name that the original, but with a different class for instantiation. Notice that, for matters of compatibility, is a good advice to implement the same interfaces the original does, that is: follow the same conventions that the original service in order of guarantee the compatibility.

Sorry for my english and I hope it helps