Symfony 2 EntityManager注入服务


96

我已经创建了自己的服务,并且需要注入原则EntityManager,但是我没有看到__construct()在我的服务上调用该方法,并且注入不起作用。

这是代码和配置:

<?php

namespace Test\CommonBundle\Services;
use Doctrine\ORM\EntityManager;

class UserService {

    /**
     *
     * @var EntityManager 
     */
    protected $em;

    public function __constructor(EntityManager $entityManager)
    {
        var_dump($entityManager);
        exit(); // I've never saw it happen, looks like constructor never called
        $this->em = $entityManager;
    }

    public function getUser($userId){
       var_dump($this->em ); // outputs null  
    }

}

这是services.yml我的包

services:
  test.common.userservice:
    class:  Test\CommonBundle\Services\UserService
    arguments: 
        entityManager: "@doctrine.orm.entity_manager"

我已经将.yml导入config.yml了我的应用中

imports:
    # a few lines skipped, not relevant here, i think
    - { resource: "@TestCommonBundle/Resources/config/services.yml" }

当我在控制器中致电服务时

    $userservice = $this->get('test.common.userservice');
    $userservice->getUser(123);

我得到一个对象(不为null),但是$this->em在UserService中为null,正如我已经提到的,从未调用过UserService上的构造函数

还有一件事,Controller和UserService处于不同的捆绑中(我确实需要用它来使项目井井有条),但仍然:一切正常,我什至可以调用

$this->get('doctrine.orm.entity_manager')

在用于获取UserService和获取有效(非null)EntityManager对象的同一控制器中。

看起来我缺少配置项或UserService和Doctrine配置之间的某些链接。


您是否尝试过二传手注射?有用?
gremo 2012年

如果通过“ setter注入”是指在我的服务上为EntityManager添加setter方法,并以$ this-> get('doctrine.orm.entity_manager')作为参数调用控制器,那么是的,我已经尝试过并且可以工作了。但是我真的很想通过配置使用适当的注入
Andrey Zavarin 2012年

2
我的意思是:symfony.com/doc/current/book / ...无论如何__constructor都是错误。
gremo

嗯,比我还没有尝试过二传手注射。__construct解决了该问题,但是无论如何,感谢您的帮助!
Andrey Zavarin

Answers:


112

您的类的构造方法应该调用__construct(),而不是__constructor()

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

2
嗨,在此示例中,如何将连接从默认更改为其他任何连接?
ptmr.io

是的,但是如果使用接口,那就更好了。public function __construct(EntityManagerInterface $entityManager)
Hugues D

65

作为现代参考,在Symfony 2.4+中,您不能再为Constructor Injection方法命名。根据文档,您将传递:

services:
    test.common.userservice:
        class:  Test\CommonBundle\Services\UserService
        arguments: [ "@doctrine.orm.entity_manager" ]

然后,它们将按照通过参数列出的顺序可用(如果超过1个)。

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

8
您可以执行以下操作:app / console container:debug并找出您正在运行的服务。
硬健身

18

从Symfony 3.3开始,EntityManager已弃用。请改用EntityManagerInterface。

namespace AppBundle\Service;

use Doctrine\ORM\EntityManagerInterface;

class Someclass {
    protected $em;

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

    public function somefunction() {
        $em = $this->em;
        ...
    }
}

1
以防万一有人跌跌撞撞地感到困惑:EntityManager当然没有贬值。建议使用该接口进行自动接线,但建议不要这样做。而且界面已经存在很长时间了。这里没有什么新鲜的。
Cerad

这就是答案。但是,请参考:stackoverflow.com/questions/22154558/…–
tfont

更新到我自己的解决方案。现在正确的方法应该是使用实体和存储库。实体管理器已经自然地注入到存储库中。您可以在此处看到一个示例:youtu.be/AHVtOJDTx0M
Robert Saylor

7

从2017年和Symfony 3.3开始,您可以将Repository作为服务注册,并具有其所有优点。

请查看我的文章如何在Symfony中将存储库与Doctrine即服务一起使用以获取更一般的描述。


对于您的特定情况,经过调整的原始代码如下所示:

1.在您的服务或控制器中使用

<?php

namespace Test\CommonBundle\Services;

use Doctrine\ORM\EntityManagerInterface;

class UserService
{
    private $userRepository;

    // use custom repository over direct use of EntityManager
    // see step 2
    public function __constructor(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function getUser($userId)
    {
        return $this->userRepository->find($userId);
    }
}

2.创建新的自定义存储库

<?php

namespace Test\CommonBundle\Repository;

use Doctrine\ORM\EntityManagerInterface;

class UserRepository
{
    private $repository;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->repository = $entityManager->getRepository(UserEntity::class);
    }

    public function find($userId)
    {
        return  $this->repository->find($userId);
    }
}

3.注册服务

# app/config/services.yml
services:
    _defaults:
        autowire: true

    Test\CommonBundle\:
       resource: ../../Test/CommonBundle
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.