diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst index 1c98bc7d471..c2b4c75fd23 100644 --- a/service_container/service_subscribers_locators.rst +++ b/service_container/service_subscribers_locators.rst @@ -243,6 +243,55 @@ service type to a service. The ``key`` attribute can be omitted if the service name internally is the same as in the service container. +Add Dependency Injection Attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 6.2 + + The ability to add attributes was introduced in Symfony 6.2. + +As an alternate to aliasing services in your configuration, you can also configure +the following dependency injection attributes in the ``getSubscribedServices()`` +method directly: + +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autowire` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\MapDecorated` + +This is done by having ``getSubscribedServices()`` return an array of +:class:`Symfony\\Contracts\\Service\\Attribute\\SubscribedService` objects +(these can be combined with standard ``string[]`` values):: + + use Psr\Container\ContainerInterface; + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; + use Symfony\Component\DependencyInjection\Attribute\TaggedLocator; + use Symfony\Component\DependencyInjection\Attribute\Target; + use Symfony\Contracts\Service\Attribute\SubscribedService; + + public static function getSubscribedServices(): array + { + return [ + // ... + new SubscribedService('logger', LoggerInterface::class, attributes: new Autowire(service: 'monolog.logger.event')), + + // can event use parameters + new SubscribedService('env', string, attributes: new Autowire('%kernel.environment%')), + + // Target + new SubscribedService('event.logger', LoggerInterface::class, attributes: new Target('eventLogger')), + + // TaggedIterator + new SubscribedService('loggers', 'iterable', attributes: new TaggedIterator('logger.tag')), + + // TaggedLocator + new SubscribedService('handlers', ContainerInterface::class, attributes: new TaggedLocator('handler.tag')), + ]; + } + Defining a Service Locator -------------------------- @@ -256,7 +305,7 @@ argument of type ``service_locator``: # config/services.yaml services: App\CommandBus: - arguments: + arguments: - !service_locator App\FooCommand: '@app.command_handler.foo' App\BarCommand: '@app.command_handler.bar' @@ -721,4 +770,63 @@ and compose your services with them:: as this will include the trait name, not the class name. Instead, use ``__CLASS__.'::'.__FUNCTION__`` as the service id. +SubscribedService Attributes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 6.2 + + The ability to add attributes was introduced in Symfony 6.2. + +You can use the ``attributes`` argument of ``SubscribedService`` to add any +of the following dependency injection attributes: + +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Autowire` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedIterator` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\TaggedLocator` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\Target` +* :class:`Symfony\\Component\\DependencyInjection\\Attribute\\MapDecorated` + +Here's an example:: + + // src/Service/MyService.php + namespace App\Service; + + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + use Symfony\Component\DependencyInjection\Attribute\Target; + use Symfony\Component\Routing\RouterInterface; + use Symfony\Contracts\Service\Attribute\SubscribedService; + use Symfony\Contracts\Service\ServiceSubscriberInterface; + use Symfony\Contracts\Service\ServiceSubscriberTrait; + + class MyService implements ServiceSubscriberInterface + { + use ServiceSubscriberTrait; + + public function doSomething() + { + // $this->environment() ... + // $this->router() ... + // $this->logger() ... + } + + #[SubscribedService(attributes: new Autowire('%kernel.environment%'))] + private function environment(): string + { + return $this->container->get(__METHOD__); + } + + #[SubscribedService(attributes: new Autowire(service: 'router'))] + private function router(): RouterInterface + { + return $this->container->get(__METHOD__); + } + + #[SubscribedService(attributes: new Target('requestLogger'))] + private function logger(): LoggerInterface + { + return $this->container->get(__METHOD__); + } + } + .. _`Command pattern`: https://en.wikipedia.org/wiki/Command_pattern
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: