2014-03-27 49 views
1

我试图创建一个Symfony2的服务,以自动传递到Doctrine\ORM\EntityManager__construct避免到每个I类实例化时通过它,即@ doctrine.orm.entity_manager不给予注册为服务类

// 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

我已经通过控制台清除缓存和手动删除应用程序/缓存,但我还是看到此错误:

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; 

有什么我错过了?

回答

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! 
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 
+0

感谢。所以我不能为EntityManagerUser定义一个服务,然后扩展这个类,我必须将每个类定义为一个服务,我想将entity_manager注入到该服务中? – Popnoodles

+0

我很遗憾地说,但是,只是扩展宣布为服务的类是不够的。 – Chausser

+0

好吧,那就是我想要避免的行数越少越好。只是宣布它是全球性的,这很诱人。 – Popnoodles