Thomas Calvet
Contributed by Thomas Calvet in #36470

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.

Published in #Living on the edge