Skip to content

Commit 31ba109

Browse files
committed
minor #18892 [DependencyInjection] Reword the explanation about index_by and default_index_method (javiereguiluz)
This PR was squashed before being merged into the 5.4 branch. Discussion ---------- [DependencyInjection] Reword the explanation about index_by and default_index_method Fixes #18725. Commits ------- 87e5baa [DependencyInjection] Reword the explanation about index_by and default_index_method
2 parents 4cc5da1 + 87e5baa commit 31ba109

File tree

2 files changed

+79
-78
lines changed

2 files changed

+79
-78
lines changed

service_container/service_subscribers_locators.rst

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -507,12 +507,15 @@ will share identical locators among all the services referencing them::
507507
Indexing the Collection of Services
508508
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
509509

510-
Services passed to the service locator can define their own index using an
511-
arbitrary attribute whose name is defined as ``index_by`` in the service locator.
510+
By default, services passed to the service locator are indexed using their service
511+
IDs. You can change this behavior with two options of the tagged locator (``index_by``
512+
and ``default_index_method``) which can be used independently or combined.
512513

513-
In the following example, the ``App\Handler\HandlerCollection`` locator receives
514-
all services tagged with ``app.handler`` and they are indexed using the value
515-
of the ``key`` tag attribute (as defined in the ``index_by`` locator option):
514+
The ``index_by`` / ``indexAttribute`` Option
515+
............................................
516+
517+
This option defines the name of the option/attribute that stores the value used
518+
to index the services:
516519

517520
.. configuration-block::
518521

@@ -592,12 +595,13 @@ of the ``key`` tag attribute (as defined in the ``index_by`` locator option):
592595
593596
$services->set(App\Handler\HandlerCollection::class)
594597
// inject all services tagged with app.handler as first argument
595-
->args([tagged_locator('app.handler', 'key')])
598+
->args([tagged_locator('app.handler', indexAttribute: 'key')])
596599
;
597600
};
598601
599-
Inside this locator you can retrieve services by index using the value of the
600-
``key`` attribute. For example, to get the ``App\Handler\Two`` service::
602+
In this example, the ``index_by`` option is ``key``. All services define that
603+
option/attribute, so that will be the value used to index the services. For example,
604+
to get the ``App\Handler\Two`` service::
601605

602606
// src/Handler/HandlerCollection.php
603607
namespace App\Handler;
@@ -608,31 +612,25 @@ Inside this locator you can retrieve services by index using the value of the
608612
{
609613
public function __construct(ServiceLocator $locator)
610614
{
615+
// this value is defined in the `key` option of the service
611616
$handlerTwo = $locator->get('handler_two');
612617
}
613618

614619
// ...
615620
}
616621

617-
Instead of defining the index in the service definition, you can return its
618-
value in a method called ``getDefaultIndexName()`` inside the class associated
619-
to the service::
620-
621-
// src/Handler/One.php
622-
namespace App\Handler;
622+
If some service doesn't define the option/attribute configured in ``index_by``,
623+
Symfony applies this fallback process:
623624

624-
class One
625-
{
626-
public static function getDefaultIndexName(): string
627-
{
628-
return 'handler_one';
629-
}
625+
#. If the service class defines a static method called ``getDefault<CamelCase index_by value>Name``
626+
(in this example, ``getDefaultKeyName()``), call it and use the returned value;
627+
#. Otherwise, fall back to the default behavior and use the service ID.
630628

631-
// ...
632-
}
629+
The ``default_index_method`` Option
630+
...................................
633631

634-
If you prefer to use another method name, add a ``default_index_method``
635-
attribute to the locator service defining the name of this custom method:
632+
This option defines the name of the service class method that will be called to
633+
get the value used to index the services:
636634

637635
.. configuration-block::
638636

@@ -647,7 +645,7 @@ attribute to the locator service defining the name of this custom method:
647645
class CommandBus
648646
{
649647
public function __construct(
650-
#[TaggedLocator('app.handler', 'key', defaultIndexMethod: 'myOwnMethodName')]
648+
#[TaggedLocator('app.handler', defaultIndexMethod: 'getLocatorKey')]
651649
ServiceLocator $locator
652650
) {
653651
}
@@ -659,8 +657,9 @@ attribute to the locator service defining the name of this custom method:
659657
services:
660658
# ...
661659
662-
App\HandlerCollection:
663-
arguments: [!tagged_locator { tag: 'app.handler', index_by: 'key', default_index_method: 'myOwnMethodName' }]
660+
App\Handler\HandlerCollection:
661+
# inject all services tagged with app.handler as first argument
662+
arguments: [!tagged_locator { tag: 'app.handler', default_index_method: 'getLocatorKey' }]
664663
665664
.. code-block:: xml
666665
@@ -672,11 +671,11 @@ attribute to the locator service defining the name of this custom method:
672671
https://symfony.com/schema/dic/services/services-1.0.xsd">
673672
674673
<services>
675-
676674
<!-- ... -->
677675
678676
<service id="App\HandlerCollection">
679-
<argument type="tagged_locator" tag="app.handler" index-by="key" default-index-method="myOwnMethodName"/>
677+
<!-- inject all services tagged with app.handler as first argument -->
678+
<argument type="tagged_locator" tag="app.handler" default-index-method="getLocatorKey"/>
680679
</service>
681680
</services>
682681
</container>
@@ -687,17 +686,27 @@ attribute to the locator service defining the name of this custom method:
687686
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
688687
689688
return function(ContainerConfigurator $container) {
690-
$container->services()
691-
->set(App\HandlerCollection::class)
692-
->args([tagged_locator('app.handler', 'key', 'myOwnMethodName')])
689+
$services = $container->services();
690+
// ...
691+
692+
$services->set(App\Handler\HandlerCollection::class)
693+
// inject all services tagged with app.handler as first argument
694+
->args([tagged_locator('app.handler', defaultIndexMethod: 'getLocatorKey')])
693695
;
694696
};
695697
696-
.. note::
698+
If some service class doesn't define the method configured in ``default_index_method``,
699+
Symfony will fall back to using the service ID as its index inside the locator.
700+
701+
Combining the ``index_by`` and ``default_index_method`` Options
702+
...............................................................
703+
704+
You can combine both options in the same locator. Symfony will process them in
705+
the following order:
697706

698-
Since code should not be responsible for defining how the locators are
699-
going to be used, a configuration key (``key`` in the example above) must
700-
be set so the custom method may be called as a fallback.
707+
#. If the service defines the option/attribute configured in ``index_by``, use it;
708+
#. If the service class defines the method configured in ``default_index_method``, use it;
709+
#. Otherwise, fall back to using the service ID as its index inside the locator.
701710

702711
.. _service-subscribers-service-subscriber-trait:
703712

service_container/tags.rst

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -922,12 +922,15 @@ you can define it in the configuration of the collecting service:
922922
Tagged Services with Index
923923
~~~~~~~~~~~~~~~~~~~~~~~~~~
924924

925-
If you want to retrieve a specific service within the injected collection
926-
you can use the ``index_by`` and ``default_index_method`` options of the
927-
argument in combination with ``!tagged_iterator``.
925+
By default, tagged services are indexed using their service IDs. You can change
926+
this behavior with two options of the tagged iterator (``index_by`` and
927+
``default_index_method``) which can be used independently or combined.
928928

929-
Using the previous example, this service configuration creates a collection
930-
indexed by the ``key`` attribute:
929+
The ``index_by`` / ``indexAttribute`` Option
930+
............................................
931+
932+
This option defines the name of the option/attribute that stores the value used
933+
to index the services:
931934

932935
.. configuration-block::
933936

@@ -1012,10 +1015,9 @@ indexed by the ``key`` attribute:
10121015
;
10131016
};
10141017
1015-
After compilation the ``HandlerCollection`` is able to iterate over your
1016-
application handlers. To retrieve a specific service from the iterator, call the
1017-
``iterator_to_array()`` function and then use the ``key`` attribute to get the
1018-
array element. For example, to retrieve the ``handler_two`` handler::
1018+
In this example, the ``index_by`` option is ``key``. All services define that
1019+
option/attribute, so that will be the value used to index the services. For example,
1020+
to get the ``App\Handler\Two`` service::
10191021

10201022
// src/Handler/HandlerCollection.php
10211023
namespace App\Handler;
@@ -1026,43 +1028,23 @@ array element. For example, to retrieve the ``handler_two`` handler::
10261028
{
10271029
$handlers = $handlers instanceof \Traversable ? iterator_to_array($handlers) : $handlers;
10281030

1031+
// this value is defined in the `key` option of the service
10291032
$handlerTwo = $handlers['handler_two'];
10301033
}
10311034
}
10321035

1033-
You can omit the index attribute (``key`` in the previous example) by setting
1034-
the ``index_by`` attribute on the ``tagged_iterator`` tag. In this case, you
1035-
must define a static method whose name follows the pattern:
1036-
``getDefault<CamelCase index_by value>Name``.
1037-
1038-
For example, if ``index_by`` is ``handler``, the method name must be
1039-
``getDefaultHandlerName()``:
1040-
1041-
.. code-block:: yaml
1036+
If some service doesn't define the option/attribute configured in ``index_by``,
1037+
Symfony applies this fallback process:
10421038

1043-
# config/services.yaml
1044-
services:
1045-
# ...
1039+
#. If the service class defines a static method called ``getDefault<CamelCase index_by value>Name``
1040+
(in this example, ``getDefaultKeyName()``), call it and use the returned value;
1041+
#. Otherwise, fall back to the default behavior and use the service ID.
10461042

1047-
App\HandlerCollection:
1048-
arguments: [!tagged_iterator { tag: 'app.handler', index_by: 'handler' }]
1043+
The ``default_index_method`` Option
1044+
...................................
10491045

1050-
.. code-block:: php
1051-
1052-
// src/Handler/One.php
1053-
namespace App\Handler;
1054-
1055-
class One
1056-
{
1057-
// ...
1058-
public static function getDefaultHandlerName(): string
1059-
{
1060-
return 'handler_one';
1061-
}
1062-
}
1063-
1064-
You also can define the name of the static method to implement on each service
1065-
with the ``default_index_method`` attribute on the tagged argument:
1046+
This option defines the name of the service class method that will be called to
1047+
get the value used to index the services:
10661048

10671049
.. configuration-block::
10681050

@@ -1089,7 +1071,6 @@ with the ``default_index_method`` attribute on the tagged argument:
10891071
# ...
10901072
10911073
App\HandlerCollection:
1092-
# use getIndex() instead of getDefaultIndexName()
10931074
arguments: [!tagged_iterator { tag: 'app.handler', default_index_method: 'getIndex' }]
10941075
10951076
.. code-block:: xml
@@ -1105,7 +1086,6 @@ with the ``default_index_method`` attribute on the tagged argument:
11051086
<!-- ... -->
11061087
11071088
<service id="App\HandlerCollection">
1108-
<!-- use getIndex() instead of getDefaultIndexName() -->
11091089
<argument type="tagged_iterator"
11101090
tag="app.handler"
11111091
default-index-method="getIndex"
@@ -1127,14 +1107,26 @@ with the ``default_index_method`` attribute on the tagged argument:
11271107
11281108
// ...
11291109
1130-
// use getIndex() instead of getDefaultIndexName()
11311110
$services->set(HandlerCollection::class)
11321111
->args([
11331112
tagged_iterator('app.handler', null, 'getIndex'),
11341113
])
11351114
;
11361115
};
11371116
1117+
If some service class doesn't define the method configured in ``default_index_method``,
1118+
Symfony will fall back to using the service ID as its index inside the tagged services.
1119+
1120+
Combining the ``index_by`` and ``default_index_method`` Options
1121+
...............................................................
1122+
1123+
You can combine both options in the same collection of tagged services. Symfony
1124+
will process them in the following order:
1125+
1126+
#. If the service defines the option/attribute configured in ``index_by``, use it;
1127+
#. If the service class defines the method configured in ``default_index_method``, use it;
1128+
#. Otherwise, fall back to using the service ID as its index inside the tagged services collection.
1129+
11381130
.. _tags_as-tagged-item:
11391131

11401132
The ``#[AsTaggedItem]`` attribute

0 commit comments

Comments
 (0)