Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony3 controller constructor injection is not working

Tags:

php

symfony

I want to pass the EntityManager instance into the constructor of my controller, using this code:

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\ORM\EntityManager;

class UserController extends Controller
{

    public function __construct( EntityManager $entityManager )
    {
        // do some stuff with the entityManager
    }
}

I do the constructor injection by putting the parameters into the service.yml file:

parameters:
#    parameter_name: value

services:
#    service_name:
#        class: AppBundle\Directory\ClassName
#        arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
    app.user_controller:
        class: AppBundle\Controller\UserController
        arguments: ['@doctrine.orm.entity_manager']

the service.yml is included in the config.yml and when I run

php bin/console debug:container app.user_controller

I get:

 Information for Service "app.user_controller"
 =============================================

 ------------------ ------------------------------------- 
  Option             Value                                
 ------------------ ------------------------------------- 
  Service ID         app.user_controller                  
  Class              AppBundle\Controller\UserController  
  Tags               -                                    
  Public             yes                                  
  Synthetic          no                                   
  Lazy               no                                   
  Shared             yes                                  
  Abstract           no                                   
  Autowired          no                                   
  Autowiring Types   -                                    
 ------------------ ------------------------------------- 

However, calling a route which is mapped to my controller, I get:

FatalThrowableError in UserController.php line 17: Type error: Argument 1 passed to AppBundle\Controller\UserController::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /home/michel/Documents/Terminfinder/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php on line 202

I cant figure out, why the EntityManager is not getting injected?

like image 616
ltsstar Avatar asked Jan 21 '17 12:01

ltsstar


1 Answers

When using the base classController.php the Container is usually auto-wired by the framework in theControllerResolver.

Basically you are trying to mix up how things actually work.

To solve your problem you basically have two solutions:

  1. Do no try to inject the dependency but fetch it directly from the Container from within your action/method.

public function listUsers(Request $request) { $em = $this->container->get('doctrine.orm.entity_manager'); }

  1. Create a controller manually but not extend the Controller base class; and set ip up as a service

To go a bit further on this point, some people will advise to do not use the default Controller provided by Symfony.

While I totally understand their point of view, I'm slightly more moderated on the subject.

The idea behind injecting only the required dependencies is to avoid and force people to have thin controller, which is a good thing.

However, with a little of auto-determination, using the existing shortcut is much simpler.

A Controller / Action is nothing more but the glue between your Views and your Domain/Models.

Prevent yourself from doing too much in your Controller using the ContainerAware facility.

A Controller can thrown away without generate business changes in your system.

like image 195
Boris Guéry Avatar answered Nov 14 '22 23:11

Boris Guéry