Roland Franssen
Contributed by Roland Franssen in #22200

In some Symfony applications is common to get all services tagged with a specific tag. The traditional solution was to create a compiler pass, find those services and iterate over them. However, this is overkill when you just need to get those tagged services. That's why in Symfony 3.4, we've added a shortcut to achieve the same result without having to create that compiler pass.

When using YAML configuration, add the !tagged nameOfTag notation in the arguments property of any service to inject all the services tagged with the given tag. For example, to inject all Twig extensions:

1
2
3
services:
    App\Manager\TwigManager:
        arguments: [!tagged twig.extension]

Now you can get those Twig extensions in your service and iterate over them:

1
2
3
4
5
6
7
8
9
10
// src/App/Manager/TwigManager.php
namespace App\Manager;

class TwigManager
{
    public function __construct(iterable $twigExtensions)
    {
        // ...
    }
}

If you prefer XML configuration instead of YAML, use the following syntax:

1
2
3
4
5
<services>
    <service id="App\Manager\TwigManager">
        <argument type="tagged" tag="twig.extension" />
    </service>
</services>

Finally, if you need to get the tagged services in a specific order, use the priority attribute on the tagged services.

Published in #Living on the edge