Inject tagged services in service locators
Contributed by Ion Bazan
in #43015.
In Symfony 5.4 you can use tagged iterators as arguments of service locators, which simplifies the injection of tagged services in other services. The following example shows how to use this feature when using YAML config (it works with XML and PHP config too):
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15
config/services.yaml
services: _instanceof: App\Command\HandlerInterface: tags: ['app.command_handler']
app.command_handlers:
class: Symfony\Component\DependencyInjection\ServiceLocator
arguments: [!tagged_iterator { tag: 'app.command_handler', default_index_method: 'getCommandName' }]
App\CommandBus:
arguments: ['@app.command_handlers']
App\AnotherCommandBus:
arguments: ['@app.command_handlers']
Autowire union and intersection types
Contributed by Nicolas Grekas
in #43479.
PHP 8.0 added union types (e.g. ClassA | ClassB $variable) and PHP 8.1 adds intersection types (ClassA & ClassB $variable). In Symfony 5.4 we've improved the DependencyInjection component to support both. For example:
1
2 3 4 public function __construct(NormalizerInterface & DenormalizerInterface $serializer) { // ... }
Autowiring of intersection types works when both types have a corresponding autowiring alias, and if both aliases point to the very same service.
New config options for TaggedIterator and TaggedLocator attributes
Contributed by Mykhailo Shtanko
in #43386.
When using tagged iterators and locators for your services, you can define tagged services with priority and tagged services with index. In Symfony 5.4 we've improved the TaggedIterator and TaggedLocator attributes so you can define those options in the attributes too:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 use Psr\Container\ContainerInterface; use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
public function __construct(
[TaggedIterator(tag: '...', defaultPriorityMethod: 'getPriority')]
private iterable $argument,
) { }
public function __construct(
[TaggedLocator(tag: '...', defaultIndexMethod: 'getDefaultFooName')]
private ContainerInterface $argument,
) { }
Added a new SubscribedService attribute
Contributed by Kevin Bond
in #42238.
In previous Symfony versions, the ServiceSubscriberTrait could be used to inject services in some of your class methods. This trait looks for all methods in your class that have no arguments and a return type to provide a ServiceLocator for the services of those return types. This behavior works well most of the times, but in some cases it's common to have such a method (no arguments but a return type) which shouldn't get any services injected. That's why in Symfony 5.4 we've deprecated that behavior and introduced a new SubscribedService PHP attribute. Add that attribute to any method in which you want a service injected:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 use Psr\Log\LoggerInterface; use Symfony\Component\Routing\RouterInterface; use Symfony\Contracts\Service\Attribute\SubscribedService; use Symfony\Contracts\Service\ServiceSubscriberInterface;
class MyService implements ServiceSubscriberInterface {
[SubscribedService]
private function router(): RouterInterface
{
return $this->container->get(__METHOD__);
}
#[SubscribedService]
private function logger(): LoggerInterface
{
return $this->container->get(__METHOD__);
}
// ...
}
Autoconfigurable methods, properties and parameters
Contributed by Ruud Kamphuis
in #42039.
In Symfony you can autoconfigure classes annotated with attributes using some code like the following in your dependency injection extension:
1
2 3 4 5 6 $container->registerAttributeForAutoconfiguration( MyAttribute::class, static function (ChildDefinition $definition, MyAttribute $attribute, \ReflectionClass $reflector): void { $definition->addTag('my_tag', ['some_property' => $attribute->someProperty]); } );
In Symfony 5.4 we've improved this feature to allow you to also autoconfigure methods, properties and parameters. First, make sure that you have some PHP attribute defined in your application that allows using them on methods and properties. Now, use that PHP attribute in some method and/or property:
1
2 3 4 5 6 7 8
[MyAttribute]
class MyService { }
class MyOtherService {
[MyAttribute]
public function myMethod() {}
}
You can now use the registerAttributeForAutoconfiguration() method in your extension, together with a union of the types that you want to search for. In this example, the extension only cares for classes and methods, so it uses \ReflectionClass|\ReflectionMethod $reflector:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 final class MyBundleExtension extends Extension { public function load(array $configs, ContainerBuilder $container) : void { $container->registerAttributeForAutoconfiguration( MyAttribute::class, static function (ChildDefinition $definition, MyAttribute $attribute, \ReflectionClass|\ReflectionMethod $reflector) : void { $args = []; if ($reflector instanceof \ReflectionMethod) { $args['method'] = $reflector->getName(); } $definition->addTag('my.tag', $args); } ); } }
Sponsor the Symfony project.
Login to add comment
Other posts in this group

The international Symfony conference of the year, SymfonyCon Amsterdam 2025, will take place in the Netherlands on November 27 & 28, 2025!
⏳ Early bird registration ends this Wednesday! D

This week, the upcoming Symfony 7.3 version entered its feature freeze period to tweak and polish its new features before releasing it at the end of May 2025. In addition, we celebrated the SymfonyLiv

Nous sommes heureux de vous annoncer le retour des meetups Symfony à Tunis !🎉 Rejoignez dès maintenant le groupe "Symfony User group Tunis" pour suivre les actualités et futurs meetup de la communauté

This week, Symfony 6.4.20 and 7.2.5 maintenance versions were released. In addition, Symfony successfully celebrated the SymfonyLive Paris 2025 conference and continued preparations for next week's Sy

Symfony 6.4.20 has just been released. Here is the list of the most important changes since 6.4.19:
bug #60054 [Form] Use duplicate_preferred_choices to set value of ChoiceType (@aleho)
bug #5985

Symfony 7.2.5 has just been released. Here is the list of the most important changes since 7.2.4:
bug #60054 [Form] Use duplicate_preferred_choices to set value of ChoiceType (@aleho)
bug #60026

SymfonyLive Berlin 2025 is almost here! Join us next week for an exciting event filled with fresh talks, inspiring speakers, and everything you need to make the most of this incredible gatheri