Skip to content
Advertisement

Symfony – How do I get services dynamically from the container?

For an API project I want to fail very early, before the controller is dispatched, if the input data is incorrect. I’ve managed to get the validation done by using the route defaults and an event subscriber subscribing to the KernelEvents::REQUEST event.

As you can see in the code, I’m trying to get the validator from the container. My assumption here is, that because auto wire is on, it should find them, but has() is never returning true.

So what exactly am I doing wrong? I’m trying to resolve the validator automatically, I would prefer to not have to declare it explicitly in the services.yml file.

Controller (excerpt):

JavaScript

Event Subscriber (excerpt):

JavaScript
JavaScript

Advertisement

Answer

While it is no longer possible to obtain a private service from the main services container, you have the option of making it public. That would require extra developer work of course, but this will prevent it from being automatically removed/inlined and will make it available directly in the services container.

By the way, autowiring only works if the service is defined as an argument of your controller/method. In your case, Symfony does not consider the default values for the Route annotation when determining which service to inject.

If you do not want to make these types of validator services public, a possible approach is to create a custom Service Locator with all possible validator services. You can create a service tag (e.g. app.request_validator) for these services and use a flagged interface (RequestValidatorInterface) to autoconfigure them. This will allow you to manage and access all validator services through a single, unified interface:

JavaScript

In any DI extension context:

JavaScript

Then, your Event Subscriber can be injected with this small locator instead:

JavaScript

The RequestValidatorSubscriber can use PsrContainerContainerInterface as type for this locator argument.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement