One of the key features that makes developers love Symfony is the handling of deprecated features. Symfony's backward compatibility promise ("BC promise") ensures that your application will never break when upgrading between minor versions.
In Symfony 5.1 we introduced a new way to deprecate public services and turn them into private while keeping that BC promise.
In practice, this features require adding a service tag called
container.private
and a couple of tag attributes that define the package and
version where it was deprecated:
1 2 3 4 5 6
services:
foo:
# ...
public: true
tags:
- { name: 'container.private', package: 'foo/bar', 'version': '1.2' }
If your application tries to get that service directly from the container
($container->get('foo')
) you'll see the following error:
1 2
Since foo/bar 1.2: Accessing the "foo" service directly from the container
is deprecated, use dependency injection instead.
Technically this feature uses a compiler pass to create a deprecated public alias of the public service. This is done only when the code access the service directly (not when using autowiring) to avoid displaying unnecessary deprecations.
We're already using this feature in Symfony core to turn some public services
into private (e.g. the twig
service in PR #36739) and you can also start
using it in your own public bundles and private applications.
That configuration does not say anything about the deprecation of the service. It really should contain the word "deprecated" somewhere to make the meaning clear and explicit. The concept itself seems to be sound, but DX could be better.
@Josef this feature does not deprecate the service. It prepares it to become a private service in the next major version. The service itself is not deprecated (there is another feature for that already).
@Christophe you are right, but I think that @Josef means that you see the tag name "container.private" and you don't understand immediately its purpose. It's not self-explanatory. However, given that this is a "niche" and "advanced" feature, it may be OK.
Exactly.
Maybe something like container.deprecate_public would be a bit more exlicit