在实体存储库中注入容器

时间:2014-12-05 05:17:43

标签: symfony

我想在我的存储库中获取当前区域设置。这就是为什么我将容器注入我的存储库但是我收到错误,我无法弄明白。 这是我的service.yml代码

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

这是我的存储库类代码

.......

use Symfony\Component\DependencyInjection\ContainerInterface as Container;

.......

protected $container;

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

之后我收到以下错误

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

我在构造或服务中缺少什么?

3 个答案:

答案 0 :(得分:3)

您正在使用Setter Injection(在yml中)传递容器,但您在构造函数类中定义它。

BTW实体管理器已经有一个带参数的构造函数类,所以不要使用Constructor Injection,只需在类中更改您的方法:

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

答案 1 :(得分:3)

你真的有另一个主要问题。从错误消息中可以看出,您正试图使用​​实体管理器访问您的doctrine存储库。类似的东西:

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

永远不会使用服务容器代码,无论你做什么都没关系,你仍然不会注入你的容器。将存储库创建为服务需要将实体管理器用作工厂,并在services.yml文件中添加一些其他行。

类似的东西:

# 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');

这将为您提供注入容器的存储库。

@devilciuos - %locale%仅提供默认语言环境,而不是在请求中作为_locale传递的内容。不幸的是,似乎需要听众通过服务访问本地请求:https://github.com/symfony/symfony/issues/5486

答案 2 :(得分:1)

您没有将容器传递给构造函数,而是传递给setContainer。所以你要在 SurveyRepository 中声明一个公共方法setContainer

演示/ SurveyBundle /实体/ SurveyRepository.php

protected $container;

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

或将容器传递给构造函数:

DemoSurveyBundle /资源/配置/ services.yml

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

编辑: 顺便说一下,如果你只需要语言环境,那么传递%locale%参数而不是整个容器是不够的?

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

protected $locale;

public function setLocale($locale) {
     $this->locale = $locale;
}