跳到內容

服務閉包

編輯此頁面

此功能將注入的服務封裝在一個閉包中,使其能夠在需要時延遲載入。如果注入的服務實例化成本較高或僅在特定情況下使用,則此功能非常有用。服務會在首次呼叫閉包時實例化,後續所有呼叫都會傳回相同的實例,除非該服務未共享

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']

        # In case the dependency is optional
        # arguments: [!service_closure '@?mailer']

另請參閱

服務閉包可以透過使用自動裝配及其專用屬性來注入。

另請參閱

另一種延遲注入服務的方式是透過服務定位器

在編譯器傳遞中使用服務閉包

編譯器傳遞中,您可以透過將服務參考封裝到 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')));
}
本作品,包括程式碼範例,均根據 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本