I want to call service method dynamically with autowired parameters
for now I do as followed :
$result = call_user_func_array([$myService,"myMethod"],[$entityManager,$tranlator]);
The problem is that sometimes the service method needs other parameters than $entityManager and $translator.
I would like to call $myservice without specifying parameters (like i would to with dependency injection).
my method looks like this :
public function myMethod(EntityManagerInterface $em,TranslatorInterface $translator)
{
return "toto";
}
I tried another way to load my method services directly from the class constructor but since it extends another class I have to call all parents services. that not really clean
class LicensePackController extends MainController
{
public function __construct(TranslatorInterface $translator, SystemTools $systemTools, KernelInterface $kernel, Permissions $permissions, ManagerRegistry $doctrine, RequestStack $requestStack, RouterInterface $router)
{
parent::__construct($translator, $systemTools, $kernel, $permissions, $doctrine, $requestStack, $router);
}
}
I want to call service method dynamically with autowired parameters
for now I do as followed :
$result = call_user_func_array([$myService,"myMethod"],[$entityManager,$tranlator]);
The problem is that sometimes the service method needs other parameters than $entityManager and $translator.
I would like to call $myservice without specifying parameters (like i would to with dependency injection).
my method looks like this :
public function myMethod(EntityManagerInterface $em,TranslatorInterface $translator)
{
return "toto";
}
I tried another way to load my method services directly from the class constructor but since it extends another class I have to call all parents services. that not really clean
class LicensePackController extends MainController
{
public function __construct(TranslatorInterface $translator, SystemTools $systemTools, KernelInterface $kernel, Permissions $permissions, ManagerRegistry $doctrine, RequestStack $requestStack, RouterInterface $router)
{
parent::__construct($translator, $systemTools, $kernel, $permissions, $doctrine, $requestStack, $router);
}
}
Share
Improve this question
edited Nov 21, 2024 at 8:48
Chopchop
asked Nov 20, 2024 at 18:43
ChopchopChopchop
2,94920 silver badges38 bronze badges
4
- 2 Probably going to be disappointed. Lots of folks look at how Symfony calls controller action methods with what looks like dependency injection. But there is a lot of code behind that capability and it only works because only the Symfony kernel ever calls the action methods directly. It is interesting to look at how Symfony manages to do that but it is not something that PHP supports directly and not something that can be expanded. – Cerad Commented Nov 20, 2024 at 19:08
- 2 Explain the other problem you are trying to solve and maybe we could suggest a better alternative that won't require auto wiring outside the service container. – Victor Vasiloi Commented Nov 20, 2024 at 21:37
- @victor-vasiloi you're right there's other problems behind. I edited my question – Chopchop Commented Nov 21, 2024 at 8:53
- Looks like you are making custom request controllers? If so then looking at how the Symfony base controller class uses a service locator might be helpful. – Cerad Commented Nov 21, 2024 at 13:07
2 Answers
Reset to default 1Original answer
You should use constructor injection in your service:
class YourService
{
public function __construct(
private EntityManagerInterface $em,
private TranslatorInterface $translator,
) {
}
public function myMethod()
{
$this->em->getRepository(Entity::class);
// ...
return "toto";
}
}
Answer for updated question
If you can't use constructor injection you can use setter injection and #[Required]
attribute to Container automatically call it after service initialisation. Try this code:
#[Required]
public function setInjectedService(InjectedService $service): void
{
$this->service = $service;
}
After further investigation there's maybe a solution using "AutowireMethodOf Attribute" but I can't test it since I am in symfony 6.4 for now
$result = $this->container->get($myService)->$myMethod();
https://symfony/blog/new-in-symfony-7-1-new-dependency-injection-attributes
public function myMethod(
#[AutowireCallable(service: EntityManagerInterface)],
#[AutowireCallable(service: TranslatorInterface )]
)
{
return "toto";
}