Як зробити аргументи/посилання сервісів опціональними

Дата оновлення перекладу 2022-11-25

Як зробити аргументи/посилання сервісів опціональними

Іноді, один з ваших сервісім може мати опціональну залежність, що означає, що ця залежність не є необхідною для того, щоб ваш сервіс працював правильно. Ви можете сконфігурувати контейнер так, щоб він не видавав помилку у такому випадку.

Установка відсутніх залежностей як null

Ви можете використати стратегію null, щоб чітко встановити аргумент як null, якщо сервіс не існує:

  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 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
        https://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <!-- ... -->

        <service id="App\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
# config/services.yaml
services:
    App\Newsletter\NewsletterManager:
        calls:
            - setLogger: ['@?logger']

Note

Якщо аргумент виклику методу є колекцією аргументів, і відсутні якісь з них, то ці елементи будуть видалені, але метод виклику все одно буде виконано з тими елементами колекції, що залишилися.

В YAML, спеціальний синтаксис @? говорить сервіс-контейнеру, що залежність є
опціональною. Авжеж, NewsletterManager також має бути переписаний, шляхом додавання методу setLogger():

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