Замыкания сервисов
Дата обновления перевода 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']
# В случае, если зависимость не является обязательной
# arguments: [!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')));
}