Symfony 2 EntityManager 注入服务

我已经创建了自己的服务,并且需要注入原则 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"

我已经在我的应用程序中像这样导入了 config.yml中的.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) ,但是 UserService 中的 $this->em为 null,并且正如我已经提到的,UserService 上的构造函数从未被调用过

还有一件事,Controller 和 UserService 在不同的捆绑包中(我确实需要它来保持项目的组织性) ,但是仍然: 其他一切工作正常,我甚至可以调用

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

在我用来获取 UserService 和有效(非空) EntityManager 对象的同一个控制器中。

看起来好像我丢失了一个配置或者 UserService 和 Doctrine 配置之间的某个链接。

118274 次浏览

Your class's constructor method should be called __construct(), not __constructor():

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

For modern reference, in Symfony 2.4+, you cannot name the arguments for the Constructor Injection method anymore. According to the documentation You would pass in:

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

And then they would be available in the order they were listed via the arguments (if there are more than 1).

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

Note as of Symfony 3.3 EntityManager is depreciated. Use EntityManagerInterface instead.

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;
...
}
}

Since 2017 and Symfony 3.3 you can register Repository as service, with all its advantages it has.

Check my post How to use Repository with Doctrine as Service in Symfony for more general description.


To your specific case, original code with tuning would look like this:

1. Use in your services or Controller

<?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. Create new custom repository

<?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. Register services

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


Test\CommonBundle\:
resource: ../../Test/CommonBundle