Для передачи аргумента в сервис через конфигурацию есть
три способа:
1. В конструктор
2. Через сеттер
3. Напрямую в свойство
Необходимо определить, что предстоит делать с сервисами в дальнейшем. Использование алиаса в данном случае выглядит избыточным, так как можно использовать уникальный id сервиса.
Воспользуемся
последним примером со страницы:
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
class TransportCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('acme_mailer.transport_chain')) {
return;
}
// Получаем определение сервиса для хранения объектов транспорта
$definition = $container->getDefinition(
'acme_mailer.transport_chain'
);
// Получаем все сервисы транспорта то тегу
$taggedServices = $container->findTaggedServiceIds(
'acme_mailer.transport'
);
// Задаем инъекцию каждого транспорта в хранилище
foreach ($taggedServices as $id => $tagAttributes) {
// Вложенный цикл перебирает все теги каждого сервиса, здесь надо быть аккуратным
foreach ($tagAttributes as $attributes) {
$definition->addMethodCall(
'addTransport',
array(new Reference($id), $attributes["alias"])
);
}
}
}
}
Рассмотри два случая.
1. Нужно обработать данные каждым транспортом:
Из документации следует, что все экземпляры Transport окажутся в массиве у объекта TransportChain. Ключи массивов будут соответствовать алиасам. Данная схема вполне оправдана.
2. Нужно обработать данные только одним экземпляром класса Transport:
В этом случае выше приведенные затраты на создание пачки объектов класса Transport не оправданы, вместо этого проще всего изменить определение сервиса TransportChain, скармливая ему DI контейнер:
<services>
<service id="acme_mailer.transport_chain" class="TransportChain">
<call method="setDI">
<argument type="service" id="service_container" />
</call>
</service>
</services>
Далее, используя CompilerPass передать в TransportChain массив с id сервисов Transport. Данные действия позволят получить нужный транспорт по id прямиком из сервис контейнера.
$transports = array_keys($container->findTaggedServiceIds('acme_mailer.transport' ));
$definition->addMethodCall('setTransports', [ $transports ]);