diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst index cd043880282..8e1d9b16018 100644 --- a/service_container/service_subscribers_locators.rst +++ b/service_container/service_subscribers_locators.rst @@ -394,6 +394,212 @@ will share identical locators amongst all the services referencing them:: .. _`Command pattern`: https://en.wikipedia.org/wiki/Command_pattern +Tagged Services Locator Collection with Index +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to retrieve a specific service within the injected service collector +you can use the ``index_by`` and ``default_index_method`` options of the argument +in combination with ``!tagged_locator`` to define an index. + +In the following example, all services tagged with ``app.handler`` are passed as +first constructor argument to ``App\Handler\HandlerCollection``, +but we can now access a specific injected service: + +.. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + App\Handler\One: + tags: + - { name: 'app.handler', key: 'handler_one' } + + App\Handler\Two: + tags: + - { name: 'app.handler', key: 'handler_two' } + + App\HandlerCollection: + # inject all services tagged with app.handler as first argument + arguments: [!tagged_locator { tag: 'app.handler', index_by: 'key' }] + + .. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + .. code-block:: php + + // config/services.php + use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; + use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; + + $container->register(App\Handler\One::class) + ->addTag('app.handler', ['key' => 'handler_one']); + + $container->register(App\Handler\Two::class) + ->addTag('app.handler', ['key' => 'handler_two']); + + $container->register(App\Handler\HandlerCollection::class) + // inject all services tagged with app.handler as first argument + ->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('app.handler', 'key'))); + +After compilation the ``HandlerCollection`` to retrieve a specific service by it's ``key`` attribute +from the service locator injected, we just have to do ``$serviceLocator->get('handler_two');`` to +retrieve the ``handler_two`` handler:: + + // src/Handler/HandlerCollection.php + namespace App\Handler; + + use Symfony\Component\DependencyInjection\ServiceLocator; + + class HandlerCollection + { + public function __construct(ServiceLocator $locator) + { + $handlerTwo = $locator->get('handler_two'): + } + } + +.. tip:: + + You can omit the ``index_attribute_name`` attribute, by implementing a static + method ``getDefaultIndexAttributeName`` to the handler. + + Based on the previous example ``App\Handler\One`` should look like this:: + + // src/Handler/One.php + namespace App\Handler; + + class One + { + public static function getDefaultIndexName(): string + { + return 'handler_one'; + } + } + + And the configuration: + + .. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + App\Handler\One: + tags: + - { name: 'app.handler', priority: 20 } + + # ... + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // config/services.php + $container->register(App\Handler\One::class) + ->addTag('app.handler', ['priority' => 20]); + + // ... + + You also can define the name of the static method to implement on each service + with the ``default_index_method`` attribute on the argument. + + Based on the previous example ``App\Handler\One`` should look like:: + + // src/Handler/One.php + namespace App\Handler; + + class One + { + public static function someFunctionName(): string + { + return 'handler_one'; + } + } + + And the configuration: + + .. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + # ... + + App\HandlerCollection: + # inject all services tagged with app.handler as first argument + arguments: [!tagged_locator { tag: 'app.handler', index_by: 'key', default_index_method: 'someFunctionName' }] + + .. code-block:: xml + + + + + + + + + + + + + + + + + .. code-block:: php + + // config/services.php + // ... + + $container->register(App\HandlerCollection::class) + // inject all services tagged with app.handler as first argument + ->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('app.handler', 'key', 'someFunctionName'))); + +See also :doc:`tagged services ` + Service Subscriber Trait ------------------------ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy