Как сделать аргументы/ссылки сервисов необязательными¶
Иногда, один из ваших сервисов может иметь необязательную зависимость, что означает, что эта зависимость не является необходимой для того, чтобы ваш сервис правильно работал. Вы можете сконфгурировать контейнер так, чтобы он не выдавал ошибку в таком случае.
Установка отсутствующих зависимостей как null¶
Вы можете использовать стратегию null
, чтобы ясно устаовить аргумент как
null
, если сервис не существует:
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<!-- app/config/services.xml --> <?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <!-- ... --> <service id="AppBundle\Newsletter\NewsletterManager"> <argument type="service" id="logger" on-invalid="null" /> </service> </services> </container>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12
// app/config/services.php use AppBundle\Newsletter\NewsletterManager; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerInterface; // ... $container->register(NewsletterManager::class) ->addArgument(new Reference( 'logger', ContainerInterface::NULL_ON_INVALID_REFERENCE ));
Note
Стратегия “null” на сегодня не поддерживается драйвером YAML.
Игнорирование отсутствующих зависимостей¶
Поведение игнорирования отсутствующих зависимостей такое же, как и поведение “null”, кроме случаев использования внутри вызова метода, когда сам метод вызова будет удалён.
В следующем примере контейнер внедрит сервис, используя вызов метода, если сервис существуем, и удалит вызов метода, если сервиса нет:
- YAML
1 2 3 4 5 6
# app/config/services.yml services: app.newsletter_manager: class: AppBundle\Newsletter\NewsletterManager calls: - [setLogger, ['@?logger']]
- XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<!-- app/config/services.xml --> <?xml version="1.0" encoding="UTF-8" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="app.mailer"> <!-- ... --> </service> <service id="AppBundle\Newsletter\NewsletterManager"> <call method="setLogger"> <argument type="service" id="logger" on-invalid="ignore"/> </call> </service> </services> </container>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// app/config/services.php use AppBundle\Newsletter\NewsletterManager; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerInterface; $container ->register(NewsletterManager::class) ->addMethodCall('setLogger', array( new Reference( 'logger', ContainerInterface::IGNORE_ON_INVALID_REFERENCE ), )) ;
Note
Если аргумент вызова метода является коллекцией аргументов, и отсутствуют какие- либо из них, то эти элеметыбудут удалены, но метод вызова всё равно будет выполнен с оставшимися элементами коллекции.
В YAML, специальный синтаксис @?
говорит сервис-контейнеру, что зависимость
является необязательной. Конечно же, NewsletterManager
тоже должен быть переписан,
путём добавления метода setLogger()
:
public function setLogger(LoggerInterface $logger)
{
// ...
}
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.