@@ -297,6 +297,84 @@ This is done by having ``getSubscribedServices()`` return an array of
297297
298298 The above example requires using ``3.2 `` version or newer of ``symfony/service-contracts ``.
299299
300+ .. _service-locator_autowire-locator :
301+
302+ The AutowireLocator attribute
303+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
304+
305+ Another way to define a service locator is to use the
306+ :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ AutowireLocator `
307+ attribute::
308+
309+ // src/CommandBus.php
310+ namespace App;
311+
312+ use App\CommandHandler\BarHandler;
313+ use App\CommandHandler\FooHandler;
314+ use Psr\Container\ContainerInterface;
315+ use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
316+ use Symfony\Contracts\Service\ServiceSubscriberInterface;
317+
318+ class CommandBus implements ServiceSubscriberInterface
319+ {
320+ public function __construct(
321+ #[AutowireLocator(FooHandler::class, BarHandler::class)]
322+ private ContainerInterface $locator,
323+ ) {
324+ }
325+
326+ public function handle(Command $command): mixed
327+ {
328+ $commandClass = get_class($command);
329+
330+ if ($this->locator->has($commandClass)) {
331+ $handler = $this->locator->get($commandClass);
332+
333+ return $handler->handle($command);
334+ }
335+ }
336+ }
337+
338+ Just like with the ``getSubscribedServices() `` method, it is possible
339+ to define aliased services thanks to named argument, as well as optional
340+ services::
341+
342+ // src/CommandBus.php
343+ namespace App;
344+
345+ use App\CommandHandler\BarHandler;
346+ use App\CommandHandler\BazHandler;
347+ use App\CommandHandler\FooHandler;
348+ use Psr\Container\ContainerInterface;
349+ use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
350+ use Symfony\Contracts\Service\ServiceSubscriberInterface;
351+
352+ class CommandBus implements ServiceSubscriberInterface
353+ {
354+ public function __construct(
355+ #[AutowireLocator(
356+ fooHandlerAlias: FooHandler::class,
357+ barHandlerAlias: BarHandler::class,
358+ optionalBazHandlerAlias: '?'.BazHandler::class
359+ )]
360+ private ContainerInterface $locator,
361+ ) {
362+ }
363+
364+ public function handle(Command $command): mixed
365+ {
366+ $fooHandler = $this->locator->get('fooHandlerAlias');
367+
368+ // ...
369+ }
370+ }
371+
372+ .. versionadded :: 6.4
373+
374+ The
375+ :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ AutowireLocator `
376+ attribute was introduced in Symfony 6.4.
377+
300378.. _service-subscribers-locators_defining-service-locator :
301379
302380Defining a Service Locator
0 commit comments