Иногда при определении служб в ваших приложениях Symfony есть аргументы, которые нельзя добавить в конфигурационные файлы. Причина заключается в том, что их значения могут быть рассчитаны только во время выполнения на этапе компиляции или расширения пакета.
В этих случаях обычно добавляют пустой аргумент с некоторым комментарием, объясняющим, что значение будет введено позже. Например, вторым аргументом этого сервиса является полный список каталогов, в которых хранятся шаблоны Twig. Этот список доступен только при запуске приложения, поскольку пакеты могут также добавлять свои собственные каталоги:
<service id="twig.template_iterator" class="Symfony\Bundle\TwigBundle\TemplateIterator">
<argument type="service" id="kernel" />
<argument type="collection" /> <!-- Twig paths -->
<argument>%twig.default_path%</argument>
</service>
Этому другому сервису необходимо корневое пространство имен приложения, которое лучше рассчитать динамически при запуске приложения (вместо того, чтобы заставлять пользователя настраивать это значение вручную):
<service id="maker.generator" class="Symfony\Bundle\MakerBundle\Generator">
<argument type="service" id="maker.file_manager" />
<argument /> <!-- root namespace -->
</service>
В Symfony 5.1 улучшили этот конфиг, чтобы заменить «пустой аргумент + комментарий» на надлежащие абстрактные аргументы сервиса. Это аргументы, значения которых могут быть вычислены только во время выполнения в проходах компилятора или расширениях пакета.
Вот как выглядит предыдущий пример при использовании абстрактных аргументов:
<service id="maker.generator" class="Symfony\Bundle\MakerBundle\Generator">
<argument type="service" id="maker.file_manager" />
<argument type="abstract" key="$rootNamespace">defined in MakerPass</argument>
</service>
Значение ключа определяет имя аргумента в конструкторе службы, а значение, заключенное в <argument> ... </argument>
, является необязательным комментарием к аргументу. Если вы используете YAML для определения сервисов, используйте этот другой синтаксис на основе ключевого слова! abstract:
maker.generator:
class: Symfony\Bundle\MakerBundle\Generator
arguments:
$rootNamespace: !abstract defined in MakerPass
Это конфигурация, необходимая при использовании PHP:
use Symfony\Bundle\MakerBundle\Generator;
use Symfony\Component\DependencyInjection\Argument\AbstractArgument;
$builder->register('maker.generator', Generator::class)
->setArgument('$rootNamespace', new AbstractArgument('defined in MakerPass'));
Если вы не замените значение абстрактных аргументов в каком-либо проходе компилятора или расширении пакета, вы увидите следующее сообщение об ошибке:
Аргумент «$rootNamespace» службы «maker.generator» является абстрактным (определен в MakerPass), вы забыли его определить?