我正在尝试在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,因为另一项服务正常工作,我通过添加(然后删除)语法错误进行了双重检查。
我阅读了文档,this,this和this,我最终得到了以下代码,但未通过@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;
我错过了什么?
答案 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!