New in Symfony 3.4: Simpler injection of tagged services
October 6, 2017 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
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.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
This example will work only with PHP 7.1 because `iterable` as a type hint appeared only in this PHP version.
public function __construct(array < Twig_ExtensionInterface >)
One can wish for :)
public function __construct(TwigExtension ...$twigExtensions)
Btw, this is why the typehint is iterable in the example, not array. It won't be injected as an array.
Would it be possible to use type syntax as well?
There is no syntax highlighter, so here is the link to gist with example:
https://gist.github.com/TomasVotruba/5518df9beb30afe84267c6ca80311de2
That would be super awesome :)