5

Why do I have this error?

Catchable Fatal Error: Argument 1 passed to Application\Sonata\ProductBundle\Controller\ProductAdminController::__construct() must be an instance of ContainerInterface, instance of appDevDebugProjectContainer given

Here is my services.yml:

services:
    product_admin_controller:
      class: Application\Sonata\ProductBundle\Controller\ProductAdminController
      arguments: ["@service_container"]
      tags:
            - { name: doctrine.event_listener, event: postLoad, connection: default  }

And my controller:

class ProductAdminController extends Controller
{
    protected $container;

    public function __construct(\ContainerInterface $container)
    {
        $this->container = $container;
    }
}
Tokeeen.com
  • 718
  • 7
  • 19
Ophiuchus
  • 515
  • 7
  • 17
  • 1
    This seems like a mix of `Symfony`'s classic controller and Controller-as-a-service concept. Why are you both extending `Controller` and passing `Container` via `__construct`? – Jovan Perovic Jan 14 '15 at 15:55
  • 1
    Its a namespace issue. use Symfony\Component\DependencyInjection\ContainerInterface; __construct(ContainerInterface. You really should use the ContainerAware interface. Better yet, inject your specific dependencies instead of the complete container. – Cerad Jan 14 '15 at 22:00
  • Thank you all for your help. The main goal is to override an orm product class and extend it with a mongodb odm driven variation object. I try and reproduce this (http://fr.slideshare.net/jwage/doctrine-intherealworldsf-live2011sanfran) from page 32 to following. So the first try was to inject EntityManager (http://stackoverflow.com/questions/20587354/how-to-call-entity-manager-in-a-constructor) but I couldn't make it without errors so I tried (http://stackoverflow.com/questions/22128402/symfony2-injecting-security-context-to-get-the-current-user-how-to-avoid-a-s) – Ophiuchus Jan 15 '15 at 17:23

2 Answers2

3

You have to inject the container by the "calls" option, not as an argument i think :

services:
    product_admin_controller:
      class: Application\Sonata\ProductBundle\Controller\ProductAdminController
      arguments: ["@another_service_you_need"]
      tags:
            - { name: doctrine.event_listener, event: postLoad, connection: default  }
      calls:
            -   [ setContainer,["@service_container"] ]

Also, don't forget to create the public method "setContainer()" in your listener class.

Keiro
  • 31
  • 3
1

First of all, why are you trying to use __constract()? Instead you have to use setContainer() method which takes ContainerInterface $container as an argument, it should look like this:

<?php
...
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;

...
class YourClass extends Controller
{

    public function setContainer(ContainerInterface $container = null)
    {
        // your stuff
    }
}

And the second question: what for do you need the container to be injected into controller? You can call any service with $this->get('{service_id}') statement instead of direct call of container.

Alex
  • 1,073
  • 9
  • 20
  • I use the __construct() function because the mongoDB «extension» I want to make is a general behavior. I want the mongoDB variation object to always extend the mysql product object. So far, I managed to pass the EntityManager (as planned beforehand) to the function through a service, BUT, as the class is called twice, the first time, my `EntityManager $em` is an object, the second time it's `null`… I can't understand WHY? – Ophiuchus Jan 20 '15 at 17:41
  • because is the best way to do it? – danielrvt Mar 11 '15 at 01:09
  • Sorry, but I think that "because the mongoDB «extension»" does not explain anything. I still don' think you have to inject into your controller either service container or entity manager. – Alex Mar 11 '15 at 05:41