Динамическое создание сервисов в symfony 5
Столкнулся в симфони с такой проблемой.
Если мне нужен какой-либо сервис то я делаю так
class Controller
{
/**
* @var MyService
*/
private $service;
public function __construct(MyService $service)
{
$this->service = $service;
}
}
или так
class Controller2
{
public function someAction(MyService2 $service)
{
}
}
Но что если мне нужно неограниченное количество сервисов в зависимости от условий?
К примеру,
class Router {
public function match($params)
{
$someServiceClass = $this->getServiceByParams($params);
$someService = new $someServiceClass();
return $someService;
}
}
но в том же $someServiceClass в конструкторе могут быть любые сервисы, т.е. я не могу просто взять и создать
new $someServiceClass();
Например в Magento 2 есть такая штука, как ObjectManager, когда я могу сделать просто
$objectManager->get(MyClass::class)
И он вернет инстанс класса со всеми заинжекченными сервисами в конструктор.
Есть ли в симфони такая возможность?
Ответы (2 шт):
Вы можете воспользоваться контейнером симфони $this->container->get(Service::class), вот только доставать сервисы через контейнер по их названию возможно только если сервис является публичным. Вы можете сделать нужный сервис публичным таким отбразом:
Файл services.yaml
App\Service\Ваш сервис:
public: true
Можете воспользоваться Service Subscriber
class Router implements ServiceSubscriberInterface {
private $locator;
public function __construct(ContainerInterface $locator)
{
$this->locator = $locator;
}
public static function getSubscribedServices()
{
// список ваших возможных сервисов
return [
'foo' => FooService::class,
'bar' => BarService::class,
];
}
// $params = 'foo' или 'bar'
public function match($params)
{
if($this->locator->has($params) {
$someService = $this->locator->get($params);
return $someService;
}
return null;
}
}