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