Динамическое создание сервисов в 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 шт):

Автор решения: Alpha

Вы можете воспользоваться контейнером симфони $this->container->get(Service::class), вот только доставать сервисы через контейнер по их названию возможно только если сервис является публичным. Вы можете сделать нужный сервис публичным таким отбразом:

Файл services.yaml

App\Service\Ваш сервис:
    public: true
→ Ссылка
Автор решения: Dmitry Kozlov

Можете воспользоваться 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;
    }
}
→ Ссылка