New in Symfony 5.4: DependencyInjection Improvements

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.

https://symfony.com/blog/new-in-symfony-5-4-dependencyinjection-improvements?utm_source=Symfony%20Blog%20Feed&utm_medium=feed

Created 4y | Nov 23, 2021, 5:20:22 PM


Login to add comment

Other posts in this group

A Week of Symfony #973 (August 18–24, 2025)

This week, Symfony development focused on improving the IsGranted attribute with a new option, updated the Route attribute to allow setting multiple environments, improved the DomCrawler component to

Aug 24, 2025, 9:40:28 AM | Symfony
A Week of Symfony #972 (August 11–17, 2025)

This week, development activity mostly focused on dealing with the deprecation of sleep/wakeup methods in PHP 8.5 and their replacement by serialize/unserialize methods. In addition, we published more

Aug 17, 2025, 8:30:06 AM | Symfony
Let’s build the Symfony AI ecosystem together

It’s been only in July that we published symfony/ai and kicked off our AI initiative, but the repository has been busy since day one. Over 500 stars, more than 200 pull requests & issues, trending

Aug 16, 2025, 9:30:03 AM | Symfony
SymfonyCon Amsterdam 2025:   Unconference Track at SymfonyCon Amsterdam 2025

🎤 Take the stage at SymfonyCon Amsterdam 2025, on your own terms!

The Unconference track is back and more dynamic than ever!

This unique, participant-driven format invites attendees to shape

Aug 12, 2025, 12:40:20 PM | Symfony
A Week of Symfony #971 (August 4–10, 2025)

This week, Symfony completed the migration to PHPUnit 12 in the 7.4 branch, which required many changes during the past weeks, such as replacing annotations with attributes. In addition, we updated th

Aug 10, 2025, 9:40:09 AM | Symfony
SymfonyCon Amsterdam 2025:  Join the Symfony Hackathon:  Collaborate, Contribute, Create

🧑‍💻HACKDAY IS COMING!

Get ready to code, collaborate, and contribute, Symfony Hackday is back!

Join us in Amsterdam on Saturday, November 29th, for a hands-on hackathon designed to bring the

Aug 6, 2025, 10:40:04 AM | Symfony
A Week of Symfony #970 (July 28 – August 3, 2025)

This week, Symfony released the maintenance versions 6.4.24, 7.2.9, and 7.3.2. Meanwhile, we began deprecating the XML configuration format in some components, enhanced the YAML configuration format t

Aug 3, 2025, 8:30:03 AM | Symfony