@@ -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+
246295Defining 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