Symfony предоставляет ярлык для внедрения всех служб, помеченных определенным тегом, что является обычной потребностью в некоторых приложениях, поэтому вам не нужно писать пропуск компилятора только для этого. В Symfony 4.3 улучшили это, чтобы позволить доступ к тегированным сервисам по вашему собственному заданному индексу.
В следующем примере сервисы, помеченные app.handler
, определяют дополнительный атрибут с именем key
. При внедрении их в службу App\HandlerCollection
вы можете теперь определить атрибут index_by
, чтобы сообщить Symfony, какой индекс следует использовать в ассоциативном массиве, который содержит помеченные службы:
# 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
# and use the value of the 'key' tag attribute to index the services
arguments: [!tagged { tag: 'app.handler', index_by: 'key' }]
После компиляции контейнера служб, служба HandlerCollection
может перебирать обработчики, используя значения, определенные в их ключевых атрибутах:
// src/Handler/HandlerCollection.php
namespace App\Handler;
class HandlerCollection
{
public function __construct(iterable $handlers)
{
$handlers = iterator_to_array($handlers);
$handlerTwo = $handlers['handler_two'];
// ...
}
}
Вместо определения значения индекса в каждом теге службы, вы можете определить это значение в статическом методе getDefaultIndexName()
в вашем сервисе. Например, так будет выглядеть предыдущий сервис App\Handler\One
:
// src/Handler/One.php
namespace App\Handler;
class One
{
// ...
public static function getDefaultIndexName(): string
{
return 'handler_one';
}
}
Имя этого статического метода также можно настроить с помощью атрибута тега default_index_method
:
# config/services.yaml
services:
# ...
App\HandlerCollection:
arguments: [!tagged { tag: 'app.handler', default_index_method: 'someCustomMethodName' }]