Skip to content

Commit b6aa127

Browse files
committed
[DI] add docs for SubscribedService::$attributes
1 parent 93da9d5 commit b6aa127

File tree

1 file changed

+109
-1
lines changed

1 file changed

+109
-1
lines changed

service_container/service_subscribers_locators.rst

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,55 @@ service type to a service.
243243
The ``key`` attribute can be omitted if the service name internally is the
244244
same as in the service container.
245245

246+
Add Dependency Injection Attributes
247+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
248+
249+
.. versionadded:: 6.2
250+
251+
The ability to add attributes was introduced in Symfony 6.2.
252+
253+
As an alternate to aliasing services in your configuration, you can also configure
254+
the following dependency injection attributes in the ``getSubscribedServices()``
255+
method directly:
256+
257+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autowire`
258+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
259+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
260+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target`
261+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\MapDecorated`
262+
263+
This is done by having ``getSubscribedServices()`` return an array of
264+
:class:`Symfony\\Contracts\\Service\\Attribute\\SubscribedService` objects
265+
(these can be combined with standard ``string[]`` values)::
266+
267+
use Psr\Container\ContainerInterface;
268+
use Psr\Log\LoggerInterface;
269+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
270+
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
271+
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
272+
use Symfony\Component\DependencyInjection\Attribute\Target;
273+
use Symfony\Contracts\Service\Attribute\SubscribedService;
274+
275+
public static function getSubscribedServices(): array
276+
{
277+
return [
278+
// ...
279+
new SubscribedService('logger', LoggerInterface::class, attributes: new Autowire(service: 'monolog.logger.event')),
280+
281+
// can event use parameters
282+
new SubscribedService('env', string, attributes: new Autowire('%kernel.environment%')),
283+
284+
// Target
285+
new SubscribedService('event.logger', LoggerInterface::class, attributes: new Target('eventLogger')),
286+
287+
// TaggedIterator
288+
new SubscribedService('loggers', 'iterable', attributes: new TaggedIterator('logger.tag')),
289+
290+
// TaggedLocator
291+
new SubscribedService('handlers', ContainerInterface::class, attributes: new TaggedLocator('handler.tag')),
292+
];
293+
}
294+
246295
Defining a Service Locator
247296
--------------------------
248297

@@ -256,7 +305,7 @@ argument of type ``service_locator``:
256305
# config/services.yaml
257306
services:
258307
App\CommandBus:
259-
arguments:
308+
arguments:
260309
- !service_locator
261310
App\FooCommand: '@app.command_handler.foo'
262311
App\BarCommand: '@app.command_handler.bar'
@@ -721,4 +770,63 @@ and compose your services with them::
721770
as this will include the trait name, not the class name. Instead, use
722771
``__CLASS__.'::'.__FUNCTION__`` as the service id.
723772

773+
SubscribedService Attributes
774+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
775+
776+
.. versionadded:: 6.2
777+
778+
The ability to add attributes was introduced in Symfony 6.2.
779+
780+
You can use the ``attributes`` argument of ``SubscribedService`` to add any
781+
of the following dependency injection attributes:
782+
783+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autowire`
784+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator`
785+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator`
786+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target`
787+
* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\MapDecorated`
788+
789+
Here's an example::
790+
791+
// src/Service/MyService.php
792+
namespace App\Service;
793+
794+
use Psr\Log\LoggerInterface;
795+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
796+
use Symfony\Component\DependencyInjection\Attribute\Target;
797+
use Symfony\Component\Routing\RouterInterface;
798+
use Symfony\Contracts\Service\Attribute\SubscribedService;
799+
use Symfony\Contracts\Service\ServiceSubscriberInterface;
800+
use Symfony\Contracts\Service\ServiceSubscriberTrait;
801+
802+
class MyService implements ServiceSubscriberInterface
803+
{
804+
use ServiceSubscriberTrait;
805+
806+
public function doSomething()
807+
{
808+
// $this->environment() ...
809+
// $this->router() ...
810+
// $this->logger() ...
811+
}
812+
813+
#[SubscribedService(attributes: new Autowire('%kernel.environment%'))]
814+
private function environment(): string
815+
{
816+
return $this->container->get(__METHOD__);
817+
}
818+
819+
#[SubscribedService(attributes: new Autowire(service: 'router'))]
820+
private function router(): RouterInterface
821+
{
822+
return $this->container->get(__METHOD__);
823+
}
824+
825+
#[SubscribedService(attributes: new Target('requestLogger'))]
826+
private function logger(): LoggerInterface
827+
{
828+
return $this->container->get(__METHOD__);
829+
}
830+
}
831+
724832
.. _`Command pattern`: https://en.wikipedia.org/wiki/Command_pattern

0 commit comments

Comments
 (0)