Атрибут AsDecorator
Атрибут AsDecorator вешается на класс
и превращает его в декоратор указанного сервиса.
Первым параметром передаётся идентификатор
декорируемого сервиса. Декоратор оборачивает
оригинальный сервис и может изменить его
поведение до или после вызова. Вторым параметром
decorates задаётся идентификатор сервиса,
а параметром priority - приоритет
применения декоратора.
Синтаксис
#[AsDecorator(id, decorates: decorates, priority: priority)]
Пример
Давайте создадим простой сервис, который возвращает строку:
<?php
namespace AppService;
class MessageService
{
public function getMessage(): string
{
return 'hello';
}
}
?>
Теперь создадим декоратор, который оборачивает этот сервис и добавляет к сообщению текст:
<?php
namespace AppService;
use SymfonyComponentDependencyInjectionAttributeAsDecorator;
#[AsDecorator(MessageService::class)]
class DecoratedMessageService
{
public function __construct(
private MessageService $inner,
) {
}
public function getMessage(): string
{
return $this->inner->getMessage() . ' world';
}
}
?>
Результат выполнения кода:
"hello world"
Пример
Давайте укажем параметр decorates явно
и получим декоратор из контейнера по имени
исходного сервиса:
<?php
namespace AppService;
use SymfonyComponentDependencyInjectionAttributeAsDecorator;
#[AsDecorator(decorates: MessageService::class, priority: 5)]
class SecondDecorator
{
public function __construct(
private MessageService $inner,
) {
}
public function getMessage(): string
{
return $this->inner->getMessage() . '!';
}
}
?>
Теперь при запросе сервиса MessageService
контейнер вернёт самый приоритетный декоратор,
а вложенный inner будет ссылаться на
следующий по цепочке сервис.
Пример
Давайте получим декорированный сервис из контейнера в контроллере:
<?php
namespace AppController;
use AppServiceMessageService;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/message', name: 'article_message')]
public function index(MessageService $service): Response
{
return new Response($service->getMessage());
}
}
?>
Результат выполнения кода для адреса /message:
hello world!