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