如何将Doctrine Entity Manager注入Symfony 4服务

6

我有一个控制器

use Doctrine\ORM\EntityManagerInterface:
class ExampleController{
   public function someFunction(ExampleService $injectedService){
       $injectedService->serviceFunction();
    }
}

通过服务

use Doctrine\ORM\EntityManagerInterface;
class ExampleService{
    public function __construct(EntityManagerInterface $em){
        ...
    }    
}

然而,调用someFunction()失败,因为没有传递0个参数(未注入EntityManagerInterface)。我正在尝试使用Service中的EntityManager。自动装配已开启。我尝试了Symfony3的解决方案,但除非我遗漏了什么,否则它们似乎不起作用。

编辑:这是我的services.yaml:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false 

    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'

    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

1
你的代码应该与自动装配兼容,我们能看一下你的services.yaml文件吗? - Smaïne
@Smaïne 是的,现在已添加。一些Symfony 2/3解决方案包括 services: your.service.here: class: app\service\here arguments: [@doctrine.orm.entity_manager] ,但我不确定我是否放置了正确的服务和服务类,或者这是否适用于我的情况。 - BLaZuRE
你能给我错误信息吗?我的配置与你相同,但它在我的电脑上可以运行。 - Smaïne
1
如果您自己调用 someFunction() 函数,那么您就需要负责提供注入的服务。依赖注入无法为您做任何事情。 - Rufinus
你有找到解决办法吗?我也遇到了完全相同的问题。 - Rudy Broersma
4个回答

15

仅适用于Symfony 4。

use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Name; //if you use entity for example Name

class ExampleService{
    private $em;
    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    function newName($code) // for example with a entity
    {
        $name = new Name();
        $name->setCode($code); // use setter for entity

        $this->em->persist($name);
        $this->em->flush();
    }
}

1
但是出现了错误:MyService::__construct()必须实现接口Doctrine\ORM\EntityManagerInterface,但传递的是字符串 - TangMonk

5

我知道这是一篇旧文章,但以防万一有人遇到困难,这里的使用语句中有一个错别字:

use Doctrine\ORM\EntityManagerInterface: //<- see that's a colon, not a semicolon

2

同意Yarimadam的观点。服务容器、依赖注入和自动装配不是关于在方法中注入的故事。依赖项被注入到我们称之为“服务”的对象中。

应用程序启动后,服务容器通过类构造函数或“set”方法调用将一个服务注入到另一个服务中。

您的ExampleController::someFunction仅由您调用,因此该方法接收$injectedService作为参数的唯一方法是您显然传递它。这是错误的方式。


1
一个使用自动装配的经典Symfony服务使用构造函数注入方法来注入依赖项。在您的情况下,您没有构造函数。
您可以考虑添加构造函数方法并将依赖项设置为私有类属性。然后相应地使用它。
或者您可以利用setter injection
服务配置:
services:
 app.example_controller:
     class: Your\Namespace\ExampleController
     calls:
         - [setExampleService, ['@exampleService']]

控制器类:

class ExampleController
{
    private $exampleService;

    public function someFunction() {
        $this->exampleService->serviceFunction();
    }

    public function setExampleService(ExampleService $exampleService) {
        $this->exampleService = $exampleService;
    }
}

ExampleService类包含一个构造函数。尽管片段中缺少,但服务具有em属性,构造函数具有$this->em = $em。文档说明“您可以在YAML中指定[参数]”。措辞让我认为这是可选的。实际上需要吗? - BLaZuRE
你如何执行类方法 ExampleController->someFunction?你能提供一下上下文吗?如果你手动执行这个方法,你必须传递依赖项。这是预期的行为。 - Yarimadam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接