@ doctrine.orm.entity_manager未被授予注册为服务的类

时间:2014-03-27 19:30:42

标签: php symfony service doctrine

我正在尝试在Symfony2中创建一个服务,以自动将Doctrine\ORM\EntityManager传递给__construct,以避免每次实例化该类时都必须传递它,即

// use this
$TestClass= new TestClass;

// instead of this
$entityManager = $this->getDoctrine()->getEntityManager();
$TestClass= new TestClass($entityManager);

我创建了一个类EntityManagerUser,尝试将其注册为服务,TestClass扩展了它。 包含services.yml,因为另一项服务正常工作,我通过添加(然后删除)语法错误进行了双重检查。

我阅读了文档,thisthisthis,我最终得到了以下代码,但未通过@doctrine.orm.entity_manager。但是,controller_listener服务确实收到@templating

我已经通过控制台清除了缓存并手动删除了app / cache但我仍然看到了这个错误:

ContextErrorException: Catchable Fatal Error: Argument 1 passed to Test\TestBundle\ServiceUser\EntityManagerUser::__construct() must be an instance of Test\TestBundle\ServiceUser\Doctrine\ORM\EntityManager, none given, called in D:\Documents\www\Test\live\src\Test\TestBundle\Controller\MyController.php on line 84 and defined in D:\Documents\www\Test\live\src\Test\TestBundle\ServiceUser\EntityManagerUser.php line 14

services.yml

services:
    # this one doesn't throw an error and passes @templating to __construct
    test.eventlistener.before_controller_listener:
        class: Test\TestBundle\Eventlistener\BeforeControllerListener
        arguments: [ @templating ]
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

    # the following one doesn't pass @doctrine.orm.entity_manager
    test.service_user.entity_manager_user:
        class: Test\TestBundle\ServiceUser\EntityManagerUser
        arguments: [ @doctrine.orm.entity_manager ]

的src /测试/ TestBundle / ServiceUser / EntityManagerUser.php

namespace Test\TestBundle\ServiceUser;

use Doctrine\ORM\EntityManager;

class EntityManagerUser{

    protected $entityManager;

    public function __construct(EntityManager $entityManager){
        $this->entityManager = $entityManager;
        // N.B. it's not possible to do it this way:
        // $this->entityManager = new EntityManager;
    }

    // also tried public function __construct($entityManager){
    // and public function __construct(Doctrine\ORM\EntityManager $entityManager){

}

的src /测试/ TestBundle /类别/ TestClass.php

namespace Test\TestBundle\Classes\TestClass;

use Test\TestBundle\ServiceUser\EntityManagerUser;

class TestClass extends EntityManagerUser{
    /* currently no functions */
}

在我的控制器中,第84行

$test= new TestClass;
// I tested that this throws the same error, it does // $test= new EntityManagerUser;

我错过了什么?

2 个答案:

答案 0 :(得分:1)

如果通过服务构造函数调用它们,则服务只获取它们的参数:

$this->get('test.service_user.entity_manager_user');

如果您创建一个新类并扩展原始类,则将该类声明为服务doenst会产生影响。

你可以做的是将这个新类声明为服务,并且仍然扩展基类。

test.classes.test_class:
    class: Test\TestBundle\Classes\TestClass\TestClass
    arguments: [ @doctrine.orm.entity_manager ]

那么你不必在扩展类中定义构造函数,因为它是父类。

然后通过这样做来获得课程:

$testClass = $this->get('test.classes.test_class');
//will be instanceof Test\TestBundle\Classes\TestClass\TestClass

答案 1 :(得分:0)

我研究了如何做我想要的事情,每次在实例化课程中都需要时,我都没有定义entityManager。

将EntityManagerUser重命名为ContainerListener(静态类)并通过服务将@service_container注入其中是有意义的,因此它也可以返回其他类。

namespace Test\TestBundle\EventListener;

class ContainerListener{

    static $container;

    // knock out the parent::onKernelRequest function that we don't want
    public function onKernelRequest($event){
        return;
    }   

    public function __construct($container){
        self::$container = $container;
    }

    static function twig(){
        return self::$container->get('twig');
    }

    static function entityManager(){
        return self::$container->get('doctrine')->getEntityManager();
    }

    static function entityManagerConnection(){
        $entityManager = self::$container->get('doctrine')->getEntityManager();
        return $entityManager->getConnection();
    }

}

<强> services.yml

services:
    test.event_listener.container_listener:
        class: Test\TestBundle\EventListener\ContainerListener
        arguments: [ @service_container ]
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

BaseClass.php 获取entityManager

namespace Test\TestBundle\Class;
use Test\TestBundle\EventListener\ContainerListener;

class BaseClass{
    public function __construct(){
        $this->entityManager = ContainerListener::entityManager();
    }
}

TestClass.php 像其他人一样扩展BaseClass

class TestClass extends BaseClass(){
    function someFunction(){
        // etc etc

        // $this->entityManager exists with no construct and without passing it 
        $stmt = $this->entityManager->getConnection()->prepare( $some_sql );

        // etc etc
    }
}

DefaultController.php

中的某处
# nope # $entityManager = $this->getDoctrine()->getEntityManager();
# nope # $TestClass= new TestClass($entityManager);

$TestClass= new TestClass; # win!