Skip to content

Commit 3a2d65b

Browse files
committed
minor #18775 [DependencyInjection] Add #[AutowireLocator] attribute (alexandre-daubois)
This PR was merged into the 6.4 branch. Discussion ---------- [DependencyInjection] Add `#[AutowireLocator]` attribute Fix #18774 Commits ------- 408bf95 [DependencyInjection] Add `#[AutowireLocator]` attribute
2 parents 5bc5989 + 408bf95 commit 3a2d65b

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

reference/attributes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Dependency Injection
3838
* :ref:`Autowire <autowire-attribute>`
3939
* :ref:`AutowireCallable <autowiring_closures>`
4040
* :doc:`AutowireDecorated </service_container/service_decoration>`
41+
* :ref:`AutowireLocator <service-locator_autowire-locator>`
4142
* :ref:`AutowireServiceClosure <autowiring_closures>`
4243
* :ref:`Exclude <service-psr4-loader>`
4344
* :ref:`TaggedIterator <tags_reference-tagged-services>`

service_container/service_subscribers_locators.rst

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,82 @@ 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+
317+
class CommandBus
318+
{
319+
public function __construct(
320+
#[AutowireLocator(FooHandler::class, BarHandler::class)]
321+
private ContainerInterface $locator,
322+
) {
323+
}
324+
325+
public function handle(Command $command): mixed
326+
{
327+
$commandClass = get_class($command);
328+
329+
if ($this->locator->has($commandClass)) {
330+
$handler = $this->locator->get($commandClass);
331+
332+
return $handler->handle($command);
333+
}
334+
}
335+
}
336+
337+
Just like with the ``getSubscribedServices()`` method, it is possible
338+
to define aliased services thanks to named arguments, as well as optional
339+
services::
340+
341+
// src/CommandBus.php
342+
namespace App;
343+
344+
use App\CommandHandler\BarHandler;
345+
use App\CommandHandler\BazHandler;
346+
use App\CommandHandler\FooHandler;
347+
use Psr\Container\ContainerInterface;
348+
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
349+
350+
class CommandBus
351+
{
352+
public function __construct(
353+
#[AutowireLocator(
354+
fooHandlerAlias: FooHandler::class,
355+
barHandlerAlias: BarHandler::class,
356+
optionalBazHandlerAlias: '?'.BazHandler::class
357+
)]
358+
private ContainerInterface $locator,
359+
) {
360+
}
361+
362+
public function handle(Command $command): mixed
363+
{
364+
$fooHandler = $this->locator->get('fooHandlerAlias');
365+
366+
// ...
367+
}
368+
}
369+
370+
.. versionadded:: 6.4
371+
372+
The
373+
:class:`Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator`
374+
attribute was introduced in Symfony 6.4.
375+
300376
.. _service-subscribers-locators_defining-service-locator:
301377

302378
Defining a Service Locator

0 commit comments

Comments
 (0)