Как сделать аргументы/ссылки сервисов необязательными

Как сделать аргументы/ссылки сервисов необязательными

Иногда, один из ваших сервисов может иметь необязательную зависимость, что означает, что эта зависимость не является необходимой для того, чтобы ваш сервис правильно работал. Вы можете сконфгурировать контейнер так, чтобы он не выдавал ошибку в таком случае.

Установка отсутствующих зависимостей как null

Вы можете использовать стратегию null, чтобы ясно устаовить аргумент как null, если сервис не существует:

  • XML
  • PHP
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>

Note

Стратегия "null" на сегодня не поддерживается драйвером YAML.

Игнорирование отсутствующих зависимостей

Поведение игнорирования отсутствующих зависимостей такое же, как и поведение "null", кроме случаев использования внутри вызова метода, когда сам метод вызова будет удалён.

В следующем примере контейнер внедрит сервис, используя вызов метода, если сервис существуем, и удалит вызов метода, если сервиса нет:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
# app/config/services.yml
services:
    app.newsletter_manager:
        class: AppBundle\Newsletter\NewsletterManager
        calls:
            - [setLogger, ['@?logger']]

Note

Если аргумент вызова метода является коллекцией аргументов, и отсутствуют какие- либо из них, то эти элеметыбудут удалены, но метод вызова всё равно будет выполнен с оставшимися элементами коллекции.

В YAML, специальный синтаксис @? говорит сервис-контейнеру, что зависимость является необязательной. Конечно же, NewsletterManager тоже должен быть переписан, путём добавления метода setLogger():

1
2
3
4
public function setLogger(LoggerInterface $logger)
{
    // ...
}