将doctrine实体管理器添加到symfony2中的服务

时间:2015-03-15 11:41:22

标签: symfony doctrine-orm

我试图在Symfony中将实体管理器添加到我的服务层。我在网上研究过,但没有一个答案似乎对我有用。

我有一个名为AppBundle \ Controller的名称空间的类。我的班级名是MasterController。那么我究竟需要添加到我的services.yml中呢?

除此之外,我认为我只需要将EntityManager $em作为参数传递给构造函数,然后将$ em分配给$ this-> em(私有)?

E.g。

class MasterController extends Controller
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    } 
}

2 个答案:

答案 0 :(得分:1)

可以将控制器定义为服务,同时扩展框架控制器类。为什么这样?通过这样做,您可以利用基本功能,例如表单工厂,模板渲染,获取用户资料等。

同时,您可以注入所需的任何控制器特定服务。这避免了将容器用作服务定位器模式。换句话说,我们可以将服务推送到控制器,而不是让控制器提取服务。控制人员并不需要关心服务的来源,而是更加自我控制。

示例:

class PersonController extends Controller
{
    private $personRepository;

    public function __construct($personRepository)
    {
        $this->personRepository = $personRepository;
    }
    public function editAction(Request $request, $id)
    {
        $person = $this->personRepository->find($id); 

        $form = $this->createForm(new PersonFormType(), $person);

        $form->handleRequest($request);

        if ($form->isValid()) {

            // Note: I add flush/persist methods to my repositories
            // You could inject the entity manager and flush from it
            $personRepository->flush();

            return $this->redirect($this->generateUrl('wherever'));
        }

        return $this->render('person/edit.html.twig', array(
        'form' => $form->createView(),));
    }
}

使控制器成为服务:

services:
person_repository:
    class: AppBundle\Entity\PersonRepository
    factory_service: 'doctrine.orm.default_entity_manager'
    factory_method:  'getRepository'
    arguments:  
        - 'AppBundle\Entity\Person'

person_controller:
    class: AppBundle\Controller\PersonController
    calls:
      - [setContainer,['@service_container']]
    arguments: 
      -'person_repository

基本上,您最终会得到一个具有所有标准功能的标准Symfony控制器,但您可以注入控制器特定的服务,例如存储库,这反过来又使您的控制器更易于读取和调试。您永远不需要在控制器操作方法中使用$ this-> get(' service')。

使用更标准的检索实体的方法对此进行收缩:

$personRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle\Entity\Person');

正如您所看到的,标准方法不仅将控制器直接与学说联系起来,而且还要求控制器知道实体的类名。您可以决定哪种方法更容易编写,理解和维护。

答案 1 :(得分:0)

首先,如果您的MasterController扩展Symfony\Bundle\FrameworkBundle\Controller课程,那么您已经EntityManager可以使用以下内容:

$this->em = $this->getDoctrine();

但是如果你想把它自己注入你的构造函数(并且有Controller as a service),那么你需要做的就是在你的services.yml中输入:

services:
    your_controller_service:
        class: AppBundle\Controller\MasterController
        arguments: [@doctrine.orm.entity_manager]

就是这样。

修改

请注意,您需要在课程定义之前的某个位置use Doctrine\ORM\EntityManager以避免Catchable fatal error