Замикання сервісів

Дата оновлення перекладу 2025-02-24

Замикання сервісів

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// src/Service/MyService.php
namespace App\Service;

use Symfony\Component\Mailer\MailerInterface;

class MyService
{
    /**
     * @param callable(): MailerInterface
     */
    public function __construct(
        private \Closure $mailer,
    ) {
    }

    public function doSomething(): void
    {
        // ...

        $this->getMailer()->send($email);
    }

    private function getMailer(): MailerInterface
    {
        return ($this->mailer)();
    }
}

Щоб визначити замикання сервісу і впровадити його в інший сервіс, створіть
аргумент типу service_closure:

1
2
3
4
5
6
7
# config/services.yaml
services:
    App\Service\MyService:
        arguments: [!service_closure '@mailer']

        # У випадку, якщо залежність не обовʼязкова
        # аргументи: [!service_closure '@?mailer']

See also

Замикання сервісів може бути впроваджено за допомогою автомонтування та спеціальних атрибутів.

See also

Інший спосіб лінивого впровадження сервісів - за допомогою локатора сервіса.

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

У передачі компілятора ви можете створити замикання сервісу, обгорнувши посилання на сервіс в екземпляр ServiceClosureArgument:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

public function process(ContainerBuilder $container): void
{
    // ...

    $myService->addArgument(new ServiceClosureArgument(new Reference('mailer')));
}