-1

Since Symfony 5.1 injecting the Container by autowiring the Psr\Container\ContainerInterface is deprecated see https://symfony.com/doc/current/service_container.html#public-versus-private-services

In case a service still needs access to the Container, does it needs to be injected by hand for the future, or is there another, more convenient, way to inject it?

One option would be to use Autowiring by Name and inject it, whenever there's a variable called $container, however that feels like a hack.

Question: What is the best practice of giving a service access to the container, if it still depends on it in Symfony 5.1+?

wawa
  • 4,816
  • 3
  • 29
  • 52
  • All you really have to do is to add an alias to your services.yaml file. Alias ContainerInterface to the actual container service. And your code will work as before. You should eventually refactor and avoid using the container but sometimes you just need to get stuff done. – Cerad Dec 28 '20 at 13:59

1 Answers1

4

Making your services container-aware has been discouraged for quite a while. As a general rule, you should avoid making your services container-aware and instead directly pass in the required services in the constructor or via setter-injection. In some cases using a container as a service locator can be useful though. For example when you use the AbstractController or when you have a service that takes in a lot of "registered" services, e.g. for handlers/senders in a Message Bus. For those cases Symfony provides a Service Locator/Subscriber: https://symfony.com/doc/current/service_container/service_subscribers_locators.html

The major difference is, that you have to define the services for the locator/subscriber instead of having all services available, like in Symfony's internal container. You can however tag services that should go into your service locator/subscriber and then collect these tagged services, so they will be passed automatically. See: https://symfony.com/doc/current/service_container/tags.html#reference-tagged-services

dbrumann
  • 16,803
  • 2
  • 42
  • 58
  • How would you handle Parameters, injecting them through Autowiring by Name? – wawa Dec 28 '20 at 13:37
  • You mean injecting parameters into the container? I would inject them into the requiring service instead. So, no need for them in the container. If you do want them in the container, you could create your own Config-service that holds these parameters or use the service subscriber and inject them along with the container, e.g. as a parameters array. If you like, I can add a code sample for that. – dbrumann Dec 28 '20 at 13:43
  • Sorry for the late reply, I meant for example an API key the a service needs. Through the Container, you can simply call `getParameter` with the name. Is https://stackoverflow.com/a/49084402/2989952 the recommended (still) the recommended way, or is there something "better"? – wawa Dec 30 '20 at 11:07
  • Yes, binding the api key like in the answer-link or directly setting the parameter as a service argument is still recommended. Since your _service locator_, i.e. the dedicated container as described above, will use the configured services from your services.yaml, it will use those parameters. What will not work is calling `getParameter()` on your container, at least not out of the box. For that you need a dedicated service holding the parameters as described in my previous comment. – dbrumann Dec 30 '20 at 14:07