【问题标题】:Symfony 2 EntityManager injection in serviceSymfony 2 EntityManager 注入服务
【发布时间】:2017-10-21 19:03:19
【问题描述】:

我已经创建了自己的服务,我需要注入学说 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-&gt;em 为 null,正如我已经提到的,从未调用过 UserService 上的构造函数

还有一点,Controller 和 UserService 位于不同的包中(我确实需要它来保持项目的组织性),但仍然:其他一切都很好,我什至可以调用

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

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

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

【问题讨论】:

  • 你试过setter注入吗?有效吗?
  • 如果'setter injection'是指在我的服务上为EntityManager添加setter方法并使用$this->get('doctrine.orm.entity_manager')作为参数调用控制器,那么是的,我试过了,它有效。但我真的很喜欢通过配置使用正确的注入
  • 我的意思是:symfony.com/doc/current/book/… 无论如何__constructor 是错误。
  • 嗯,比我还没有尝试过setter注入。 __construct 解决了这个问题,但无论如何,谢谢你的帮助!

标签: php symfony dependency-injection


【解决方案1】:

你的类的构造方法应该被称为__construct(),而不是__constructor()

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

【讨论】:

  • 嗨,在这个例子中,我怎样才能将连接从默认更改为任何其他?
  • 对,但如果你使用接口会更好。 public function __construct(EntityManagerInterface $entityManager)
【解决方案2】:

对于现代参考,在 Symfony 2.4+ 中,您不能再命名构造函数注入方法的参数了。根据documentation 你会传入:

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

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

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

【讨论】:

  • 你可以做一个:app/console container:debug 并找出你正在运行的服务。
【解决方案3】:

注意,从 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;
        ...
    }
}

【讨论】:

  • 以防万一有人偶然发现并感到困惑:EntityManager 肯定没有贬值。使用该界面有助于自动接线,建议使用该界面,但绝不是必需的。而且界面已经存在了很长时间。这里没有什么新东西。
  • 这就是答案。但是,请参考:stackoverflow.com/questions/22154558/…
  • 更新到我自己的解决方案。现在正确的方法应该是使用实体和存储库。 Entity Manager 已经自然地注入到存储库中。你可以在这里看到一个例子:youtu.be/AHVtOJDTx0M
【解决方案4】:

自 2017 年和 Symfony 3.3 起,您可以将 Repository 注册为服务,充分利用它的所有优势。

查看我的帖子 How to use Repository with Doctrine as Service in Symfony 以获得更一般的描述。


根据您的具体情况,经过调整的原始代码如下所示:

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

【讨论】:

    猜你喜欢
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 2017-08-24
    • 2016-03-21
    • 2023-03-11
    相关资源
    最近更新 更多