Виклики методу сервісу та впровадження сетера

Дата оновлення перекладу 2023-06-15

Виклики методу сервісу та впровадження сетера

Tip

Якщо ви використовуєте автомонтування, ви можете використати #[Required], щоб автоматично сконфігурувати виклики методу .

Зазвичай ви захочете впровадити ваші залежності через конструктор. Але іноді, особливо якщо залежність опціональна, ви можете захотіти використати "впровадження сетера". Наприклад:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/Service/MessageGenerator.php
namespace App\Service;

use Psr\Log\LoggerInterface;

class MessageGenerator
{
    private $logger;

    public function setLogger(LoggerInterface $logger): void
    {
        $this->logger = $logger;
    }

    // ...
}

Щоб сконфігурувати контейнер так, щоб він викликав метод setLogger, використайте ключ calls:

1
2
3
4
5
6
# config/services.yaml
services:
    App\Service\MessageGenerator:
        # ...
        calls:
            - setLogger: ['@logger']

Щоб надати незмінні сервіси, деякі класи реалізують незмінні сетери. Такі сетери повертають новий екземпляр сконфігурованого класу замість зміни обʼєкта в якому їх було викликано:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// src/Service/MessageGenerator.php
namespace App\Service;

use Psr\Log\LoggerInterface;

class MessageGenerator
{
    private $logger;

    public function withLogger(LoggerInterface $logger): self
    {
        $new = clone $this;
        $new->logger = $logger;

        return $new;
    }

    // ...
}

Так як цей метод повертає окремий клонований екземпляр, конфігурування такого сервісу означає використання зворотного значення методу wither ($service = $service->withLogger($logger);). Конфігурація для того, щоб вказати контейнеру, що він має робити так, виглядатиме так:

1
2
3
4
5
6
# config/services.yaml
services:
    App\Service\MessageGenerator:
        # ...
        calls:
            - withLogger: !returns_clone ['@logger']

Tip

Якщо підключено автомонтування, ви також можете використовувати атрибути; у попередньому прикладі це буде:

1
2
3
4
5
6
7
8
9
10
11
/**
 * @return static
 */
#[Required]
public function withLogger(LoggerInterface $logger)
{
    $new = clone $this;
    $new->logger = $logger;

    return $new;
}

Ви також можете скористатися перевагами зворотного типу PHP 8 static замість анотації @return static. Якщо ви не хочете, щоб метод зі зворотним типом PHP 8 static та атрибут #[Required] поводилися як wither, ви можете додати анотацію @return $this, щоб відключити функцію повернення клону.