跳到内容

服务闭包

编辑此页

此功能将注入的服务包装在一个闭包中,允许在需要时延迟加载。如果注入的服务实例化成本较高或仅在某些情况下使用,这将非常有用。该服务在首次调用闭包时实例化,而所有后续调用都返回相同的实例,除非该服务未共享

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

另请参阅

服务闭包可以通过使用自动装配及其专用属性进行注入。

另请参阅

另一种延迟注入服务的方式是通过服务定位器

在编译器 Pass 中使用服务闭包

编译器 Pass 中,你可以通过将服务引用包装到 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 许可协议获得许可。
目录
    版本