Атрибут AutowireLocator
Атрибут AutowireLocator вешается на параметр
конструктора или метода и внедряет объект
ServiceLocator с набором сервисов. Первым
параметром передаётся массив имён сервисов или
классов. Вторым необязательным параметром можно
указать индекс, по которому локатор будет доступен
внутри контейнера.
В отличие от обычного Autowire, который
внедряет один сервис, AutowireLocator даёт
ленивый доступ к нескольким сервисам сразу. Сервисы
внутри локатора создаются только в момент обращения
к ним через метод get.
Синтаксис
#[AutowireLocator(services, index: index)]
Пример
Давайте внедрим локатор с двумя сервисами в конструктор контроллера:
<?php
namespace App\Controller;
use App\Service\FirstService;
use App\Service\SecondService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\HttpFoundation\Response;
class ArticleController extends AbstractController
{
public function __construct(
#[AutowireLocator([FirstService::class, SecondService::class])]
private ServiceLocator $locator,
) {
}
public function index(): Response
{
$first = $this->locator->get(FirstService::class);
return new Response($first->getName());
}
}
?>
Результат выполнения кода для адреса /:
"first"
Пример
Давайте внедрим локатор с пользовательским индексом
'handlers', чтобы обращаться к нему по имени:
<?php
namespace App\Controller;
use App\Service\FirstService;
use App\Service\SecondService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\HttpFoundation\Response;
class ArticleController extends AbstractController
{
public function __construct(
#[AutowireLocator(
[FirstService::class, SecondService::class],
index: 'handlers',
)]
private ServiceLocator $locator,
) {
}
public function index(): Response
{
if ($this->locator->has(SecondService::class)) {
$second = $this->locator->get(SecondService::class);
return new Response($second->getName());
}
return new Response('not found');
}
}
?>
Результат выполнения кода для адреса /:
"second"
Пример
Давайте посмотрим, как получить список всех зарегистрированных сервисов внутри локатора:
<?php
namespace App\Controller;
use App\Service\FirstService;
use App\Service\SecondService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\HttpFoundation\Response;
class ArticleController extends AbstractController
{
public function __construct(
#[AutowireLocator([FirstService::class, SecondService::class])]
private ServiceLocator $locator,
) {
}
public function index(): Response
{
$services = array_keys($this->locator->getProvidedServices());
return new Response(implode(', ', $services));
}
}
?>
Результат выполнения кода для адреса /:
"App\Service\FirstService, App\Service\SecondService"
Смотрите также
-
класс
ServiceLocator,
который предоставляет ленивый доступ к сервисам -
метод
get,
который возвращает сервис из локатора по идентификатору -
атрибут
Autowire,
который внедряет один сервис в параметр -
атрибут
AutowireIterator,
который внедряет итератор по тегированным сервисам