web-dev-qa-db-fra.com

Comment injecter Doctrine Entity Manager dans Symfony 4 Service

J'ai un contrôleur

use Doctrine\ORM\EntityManagerInterface:
class ExampleController{
   public function someFunction(ExampleService $injectedService){
       $injectedService->serviceFunction();
    }
}

Avec un service

use Doctrine\ORM\EntityManagerInterface;
class ExampleService{
    public function __construct(EntityManagerInterface $em){
        ...
    }    
}

Cependant, les appels à someFunction() échouent car 0 paramètre est transmis (EntityManagerInterface n'est pas en cours d'injection). J'essaie d'utiliser EntityManager à partir du service. Le câblage automatique est activé. J'ai essayé les solutions pour Symfony3 mais elles ne semblent pas fonctionner à moins que quelque chose me manque.

Edit: Voici mes services.yaml:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false 

    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'

    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']
3
BLaZuRE

D'accord avec Yarimadam. Le conteneur de services, l'injection de dépendance et l'auto-câblage ne sont pas une histoire d'injection dans des méthodes. Les dépendances injectées dans les objets que nous appelons "services".

Lorsque l'application est active, le conteneur de services est construit en injectant un service dans un autre via un constructeur de classe ou l'appel de méthode "set".

Votre ExampleController::someFunction est destiné à n'être appelé que par vous. La seule façon pour cette méthode de recevoir $injectedService en argument est que vous le passerez évidemment. C'est la mauvaise façon. 

2
Murat Erkenov

Un service classique de symfony avec autowiring utilise une méthode d’injection de constructeur pour injecter des dépendances. Dans votre cas, vous n'avez pas de constructeur.

Vous pouvez envisager d'ajouter une méthode de constructeur et de définir une dépendance sur une propriété de classe privée. Et utilisez en conséquence.

Ou vous pouvez utiliser setter injection .

Configuration du service:

services:
 app.example_controller:
     class: Your\Namespace\ExampleController
     calls:
         - [setExampleService, ['@exampleService']]

Classe de contrôleur:

class ExampleController
{
    private $exampleService;

    public function someFunction() {
        $this->exampleService->serviceFunction();
    }

    public function setExampleService(ExampleService $exampleService) {
        $this->exampleService = $exampleService;
    }
}
1
Yarimadam

Utilisez uniquement dans Symfony 4. 

use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Name; //if you use entity for example Name

class ExampleService{
    private $em;
    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    function newName($code) // for example with a entity
    {
        $name = new Name();
        $name->setCode($code); // use setter for entity

        $this->em->persist($name);
        $this->em->flush();
    }
}
0
Alban Painchault

Je sais que c'est un ancien post, mais juste au cas où quelqu'un aurait du mal à le faire, il y a une faute de frappe dans l'utilisation, comme suit:

use Doctrine\ORM\EntityManagerInterface: //<- see that's a colon, not a semicolon
0
K. Weber