skip to Main Content

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);
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    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.com/blog/new-in-symfony-7-1-new-dependency-injection-attributes

    public function myMethod(
     #[AutowireCallable(service: EntityManagerInterface)],
    #[AutowireCallable(service: TranslatorInterface )]
    )
     { 
      return "toto"; 
     }
    

  2. Original 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;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search