0

I have a Bundle named Jason/JasonSticksBundle and inside this I have a controller named StickController.

I have a service defined within Jason/JasonSticksBundle/Resources/config/services.yaml

Jason\JasonSticksBundle\Controller\StickController:
        public: true
        arguments: []
        tags: ['controller.service_arguments']

My services.yaml is loaded via JasonSticksExtension->load(), and my bundle is registered in bundles.php.

The bundle works fine as-is.

BUT

For this particular project I want to override some methods within the StickController, so I am trying to "decorate" it.

At the bottom of my regular services.yaml therefore I have the following:

App\Controller\StickController:
    decorates: Jason\JasonSticksBundle\Controller\StickController

but I get this error

You have requested a non-existent service "Jason\JasonSticksBundle\Controller\StickController".

Finally, if I run

php bin/console debug:container

I can see my service

Jason\JasonSticksBundle\Controller\StickController                              Jason\JasonSticksBundle\Controller\StickController   

All I can imagine is that my services.yaml is being registered before my StickBundle is getting registered, thus it doesn't exist at the right time. But I don't know how to change the ordering of this, or if that would even be a viable option?

Any help appreciated.

  • 1
    Is your `App\Controller\StickController` public? Who is calling the container generating the error? – Alessandro Chitolina May 06 '20 at 08:01
  • @AlessandroChitolina It is public, and I am not outright making any call to the service container, just trying to register the decoration of it within services.yaml. Sorry if I misunderstood your question. If you are asking about how the original controller service is registered then I use an Extension's load() method to load in a services.yaml for the bundle – Jason Stephenson May 06 '20 at 08:38
  • 1
    I made a little test case and confirmed the problem. I could decorate another App controller and I could decorate other services in my test bundle. I found that by eliminating the controller.service_arguments tag that it would would compile but of course that does not help much when it comes to controllers. Might try the Symfony slack channel or even a github issue. – Cerad May 06 '20 at 12:35
  • 1
    Sorry, i reformulate my second question: can you see the backtrace of the error when you decorate the controller? There should be a call to Container (or ContainerBuilder) `get`, `getDefinition` or `findDefinition`. What class/object is making that call? To see the backtrace you can call the cache clear command with `-vvv` option. – Alessandro Chitolina May 06 '20 at 13:19

1 Answers1

0

I have found a workaround, though not solved. This definitely is not the way to do it - decorate exists for a reason, and I am unsure why I can't get that to work so any advice on that would still be appreciated.

For my workaround:

I removed my controller definitions from my Bundles services.yaml, and I edited my ConfigTreeBuilder of my bundles Configuration class to include a scalarNode field to allow a class name to be passed - this class name will be the controller to override the bundles.

Then, to register the controller services without using services.yaml I modified my JasonStickExtension class, and after loading the services.yaml file (still needed for other services) I added the following:

$stickControllerDefinition = $container->findDefinition('Jason\JasonSticksBundle\Controller\StickController');
$stickControllerDefinition->addTag("controller.service_arguments");
$stickDec = $config['stick_controller_class'];
  if($stickDec!=null) {
      $stickControllerDefinition->setClass($stickDec);
   }

This is a way direct way of doing it, and as I say I really don't think it's the proper way.