diff --git a/service_container/tags.rst b/service_container/tags.rst index ff56d90c73f..524096545c2 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -585,47 +585,119 @@ application handlers:: } } -.. tip:: - The collected services can be prioritized using the ``priority`` attribute: +Tagged Services with Priority +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - .. configuration-block:: +.. versionadded:: 4.4 - .. code-block:: yaml + The ability to prioritize tagged services was introduced in Symfony 4.4. - # config/services.yaml - services: - App\Handler\One: - tags: - - { name: 'app.handler', priority: 20 } +The tagged services can be prioritized using the ``priority`` attribute, thus providing +a way to inject a sorted collection. - .. code-block:: xml +.. configuration-block:: - - - + .. code-block:: yaml - - - - - - + # config/services.yaml + services: + App\Handler\One: + tags: + - { name: 'app.handler', priority: 20 } - .. code-block:: php + .. code-block:: xml - // config/services.php - namespace Symfony\Component\DependencyInjection\Loader\Configurator; + + + - return function(ContainerConfigurator $configurator) { - $services = $configurator->services(); + + + + + + - $services->set(App\Handler\One::class) - ->tag('app.handler', ['priority' => 20]) - ; - }; + .. code-block:: php + + // config/services.php + namespace Symfony\Component\DependencyInjection\Loader\Configurator; + + return function(ContainerConfigurator $configurator) { + $services = $configurator->services(); + + $services->set(App\Handler\One::class) + ->tag('app.handler', ['priority' => 20]) + ; + }; + +.. note:: + + Note that any other custom attribute will be ignored by this feature. + + +Another option, which is particularly useful when using autoconfiguring tags, is to implement the +static ``getDefaultPriority`` method on the service itself:: - Note that any other custom attributes will be ignored by this feature. + // src/App/Handler/One.php + namespace App/Handler; + + class One + { + public static function getDefaultPriority(): int + { + return 3; + } + } + +If you want to have another method defining the priority, you can define it in the configuration of the collecting service: + +.. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + App\HandlerCollection: + # inject all services tagged with app.handler as first argument + arguments: + - !tagged_iterator { tag: app.handler, default_priority_method: getPriority } + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + // config/services.php + namespace Symfony\Component\DependencyInjection\Loader\Configurator; + + use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; + + return function (ContainerConfigurator $configurator) { + $services = $configurator->services(); + + // ... + + $services->set(App\HandlerCollection::class) + ->args([ + tagged_iterator('app.handler', null, null, 'getPriority'), + ] + ) + ; + };