8

I have a listener service. I want to read some config parameters inside it.

How can I access the service container within the listener class?

2 Answers 2

29

You can pass container parameters into your service by using the %your_param_name% notation:

services:
    kernel.listener.locale_listener:
        class: My\BundleName\Listener\LocaleListener
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        arguments: [ @router, @service_container, %your_param_name% ]

which will present itself as (in this example) the 3rd argument in your service's constructor method:

public function __construct($router, $container, $paramValue)
{
    // ...
}
Sign up to request clarification or add additional context in comments.

3 Comments

Is there a little more documentation on this? I also have a Listener as a service. In my config.yml I have some settings I wish to access in the Listener, should I configure them as arguments?
Please note that since Symfony 2.8 you have to quote those arguments: arguments: [ "@router", "@service_container", "%your_param_name%" ]
Doesn't work for me or at least with a FilterResolveEvent dispatched on behalf of kernel.response event in Symfony 4. The constructor is kept invoked with 0 arguments resulting in an exception. Searching the web doesn't give a clue but several outdated matches here at SO or in blogs just repeating that part of the truth that's in the official Symfony tutorial as well. Sorry, but this whole framework is a mess ... is there any official documentation page explaining all this "put arguments with % or @ in YAML so Event Listeners get an argument in constructor accordingly"?
-1

Resolved: We need to pass the @service_container itself as an argument to the listener service

MyBundleName/Resources/services.yml:

services:
    kernel.listener.locale_listener:
        class: My\BundleName\Listener\LocaleListener
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        arguments: [ @service_container ]

Listener Class:

class LocaleListener
{
    protected $container;

    public function __construct(\Symfony\Component\DependencyInjection\Container $container)
    {
        $this->container = $container;
    }
..

    public function Myfunction()
    {
        $languages = $this->container->getParameter('languages');
    }

}

4 Comments

Passing the whole container in this case is a Bad Idea™.
@Elnur - Why is passing the whole container a bad idea?
@Robin, because dependencies should be explicit and easy mockable for testing. Also, making your classes aware of the DIC ties them to a particular of DIC. Not good, not good.
Don't use FQDN!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.