我想使用以下代码将EntityManager实例传递给控制器的构造函数:
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\ORM\EntityManager;
class UserController extends Controller
{
public function __construct( EntityManager $entityManager )
{
// do some stuff with the entityManager
}
}
我通过将参数放入service.yml文件来执行构造函数注入:
parameters:
# parameter_name: value
services:
# service_name:
# class: AppBundle\Directory\ClassName
# arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
app.user_controller:
class: AppBundle\Controller\UserController
arguments: ['@doctrine.orm.entity_manager']
service.yml包含在config.yml中,当我运行
时php bin / console debug:container app.user_controller
我明白了:
Information for Service "app.user_controller"
=============================================
------------------ -------------------------------------
Option Value
------------------ -------------------------------------
Service ID app.user_controller
Class AppBundle\Controller\UserController
Tags -
Public yes
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autowiring Types -
------------------ -------------------------------------
但是,调用映射到我的控制器的路由,我得到:
UserController.php第17行中的FatalThrowableError:输入错误: 争论1传递给 AppBundle \ Controller \ UserController :: __ construct()必须是一个实例 Doctrine \ ORM \ EntityManager,没有给出,调用 /home/michel/Documents/Terminfinder/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php 在第202行
我无法弄清楚,为什么EntityManager没有被注入?
答案 0 :(得分:4)
使用基类Controller.php
时,Container
的框架通常会自动连接
public function listUsers(Request $request)
{
$em = $this->container->get('doctrine.orm.entity_manager');
}
。
基本上你是在试图混淆事情的实际效果。
要解决您的问题,您基本上有两个解决方案:
Controller
ControllerResolver
为了进一步了解这一点,有些人会建议不要使用Symfony提供的默认控制器。
虽然我完全理解他们的观点,但我对这个主题的态度稍微有点了。
仅注入所需依赖关系背后的想法是避免并迫使人们拥有瘦控制器, 是一件好事。
但是,通过一些自动确定,使用现有的快捷方式要简单得多。
Action
/ Views
只不过是您Domain
和Models
/ Controller
之间的粘合剂。
使用ContainerAware
工具阻止自己在Controller
中做太多事情。
如果您的系统中没有生成业务更改,则{{1}}可能会被丢弃。
答案 1 :(得分:1)
自2017年起和Symfony 3.3 + ,对控制器的本地支持即服务。
您可以保持控制器的运行方式,因为正确使用构造函数注入。
只需修改您的services.yml
:
# app/config/services.yml
services:
_defaults:
autowire: true
AppBundle\:
resouces: ../../src/AppBundle
它会:
EntityManager
)
关于 Doctrine +存储库+服务+控制器,的问题很多,所以我放下了一个general answer to a post 。 Definitelly检查您是否更喜欢构造函数注入和服务而不是静态和服务定位器。
答案 2 :(得分:-1)
您是否使用以下模式来呼叫控制器AppBundle:Default:index
?如果是的那应该是问题。如果要将控制器用作服务,则必须使用模式:app.controller_id:indexAction
,它使用服务的id加载控制器。
否则,它将尝试在不使用服务容器的情况下创建类的实例。
有关详细信息,请参阅有关此主题{0}}
的symfony文档答案 3 :(得分:-4)
实体管理器在控制器中可用,无需注入它。所需要的只是:
$em = $this->getDoctrine()->getManager();