BLaZuRE
BLaZuRE

Reputation: 2406

How to inject Doctrine Entity Manager into Symfony 4 Service

I have a controller

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

With a Service

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

However, calls to someFunction() fail due to 0 parameters being passed (the EntityManagerInterface is not being injected). I am attempting to use the EntityManager from the Service. Autowiring is on. I've tried the solutions for Symfony3 but they don't seem to work unless I'm missing something.

Edit: Here is my 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']

Upvotes: 6

Views: 22717

Answers (4)

Alban Painchault
Alban Painchault

Reputation: 151

Use only in 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();
    }
}

Upvotes: 15

K. Weber
K. Weber

Reputation: 2773

I know it's an old post, but just in case somebody struggles with this, there's a typo in the use statment:

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

Upvotes: 5

Murat Erkenov
Murat Erkenov

Reputation: 694

Agree with Yarimadam. Service container, dependency injection and autowiring is not a story about injecting into methods. Dependencies injected into objects we are calling "services".

When application is up, service container is built injecting one services into another ones via class constructor or "set" method invocation.

Your ExampleController::someFunction is intended to be called only by you, so only way how this method will receive $injectedService as an argument, is that you will pass it evidently. This is the wrong way.

Upvotes: 2

Yarimadam
Yarimadam

Reputation: 1183

A classic symfony service with autowiring uses constructor injection method to inject dependencies. In your case, you don't have a constructor.

You may consider to add a constructor method and set dependency to a private class property. And use accordingly.

Or you can utilize setter injection.

Service Configuration:

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

Controller Class:

class ExampleController
{
    private $exampleService;

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

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

Upvotes: 1

Related Questions