3

I want to get Current locale in my Repository.That's why I am injecting the Container into my Repository but I am getting error that I am unable to figure it out. This is my service.yml code

survey.repository.container_aware:
    class: Demo\SurveyBundle\Repository\SurveyRepository
    calls:
        - [ setContainer, [ @service_container ] ]

and this is my repository class code

.......

use Symfony\Component\DependencyInjection\ContainerInterface as Container;

.......

protected $container;

public function __construct(Container $container) {
     $this->container = $container;
}

After that I am getting below error

ContextErrorException: Catchable Fatal Error: Argument 1 passed to 
Demo\SurveyBundle\Entity\SurveyRepository::__construct() must implement 
interface Symfony\Component\DependencyInjection\ContainerInterface, instance of
Doctrine\ORM\EntityManager given

What I am missing in my construct or in service?

Wouter J
  • 41,455
  • 15
  • 107
  • 112
Azam Alvi
  • 6,918
  • 8
  • 62
  • 89
  • Why you're trying to inject the whole container? Be more precise and try to inject only the services you depend on, directly. – Basster Dec 05 '14 at 10:52

3 Answers3

4

You are passing the container with the Setter Injection (in the yml) but you define it in the constructor class.

BTW the entity manager already have a constructor class with arguments so don't take the Constructor Injection and simply change your method in the class as:

public function setContainer(Container $container) {
     $this->container = $container;
}
Matteo
  • 37,680
  • 11
  • 100
  • 115
4

You actually have another major issue here. From the error message it's obvious that you are trying to access your doctrine repository using the entity manager. Something like:

$repo = $em->getRepository('whatever');

The service container code is never being used and it really does not matter what you do, you still won't get your container injected. Creating a repository as a service requires using the entity manager as a factory and takes some additional lines in your services.yml file.

Something like:

# services.yml
cerad_person.person_repository.doctrine:
    class:  Cerad\Bundle\PersonBundle\Entity\PersonRepository
    factory_service: 'doctrine.orm.default_entity_manager'
    factory_method:  'getRepository'
    arguments:  
        - 'Cerad\Bundle\PersonBundle\Entity\Person'
    calls:
        - [ setContainer, [@container] ] 

// controller
$personRepo = $this->get('cerad_person.person_repository.doctrine');

That will give you a repository with the container injected.

@devilciuos - %locale% will only give you the default locale and not whatever is passed as _locale in the request. Unfortunately it seems to take a listener to access the request local via a service: https://github.com/symfony/symfony/issues/5486

Cerad
  • 48,157
  • 8
  • 90
  • 92
2

You're not passing the container to the constructor, but to setContainer. So you shouuld declare a public method setContainer in SurveyRepository:

Demo/SurveyBundle/Entity/SurveyRepository.php

protected $container;

public function setContainer(Container $container) {
     $this->container = $container;
}

or pass the container to the constructor:

DemoSurveyBundle/Resources/Config/services.yml

survey.repository.container_aware:
    class: Demo\SurveyBundle\Repository\SurveyRepository
    arguments: [@service_container]

Edit: By the way, if you only need the locale, wouldn't be enough to pass the %locale% parameter instead of the whole container?

survey.repository.container_aware:
    class: Demo\SurveyBundle\Repository\SurveyRepository
    calls:
        - [ setLocale, [ %locale%] ]

protected $locale;

public function setLocale($locale) {
     $this->locale = $locale;
}
devilcius
  • 1,764
  • 14
  • 18