Symfony2 DI的懒惰服务和输入

时间:2016-01-26 20:34:24

标签: symfony repository lazy-loading

在我们的应用程序中,我们将存储库定义为服务,如下例所示:

company.repository:
    class: AppBundle\Entity\Company
    factory: [@doctrine.orm.entity_manager, getRepository]
    arguments:
        - AppBundle\Entity\Company

这样我们就可以将它注入我们只需要特定存储库而不是整个实体管理器的服务中。它更容易测试并使我们的服务更少耦合。

E.G:

company.service:
    class: AppBundle\Services\CompanyService
    arguments:
        - @company.repository

使用构造函数类型提示它的依赖关系:

<?php

use AppBundle\Entity\CompanyRepository

public function __construct(CompanyRepository $repo)
...

现在这个列表开始变大,我正在考虑将这些存储库定义为lazy以获得一些性能。

E.G:

company.repository:
    lazy: true
    class: AppBundle\Entity\Company
    factory: [@doctrine.orm.entity_manager, getRepository]
    arguments:
        - AppBundle\Entity\Company
乍一看,它似乎有效。但经过一些测试后,我发现通过将这些服务定义为lazy

,似乎打破了类型提示

我将这些存储库定义为lazy后收到的示例Exception:

  

捕获致命错误:参数1传递给   AppBundle \ EventListener \ CompanyIdRequiredListener :: __ construct()必须   是AppBundle \ Entity \ CompanyRepository的实例,实例   AppBundleEntityCompany_000000002d9713890000000167592edede1aa99e97f8c6a4a84b995db8a0c1e9   给定

我真的对这个例外感到惊讶,因为这似乎是Symfony官方文档所描述的一个类似用例here

  

在某些情况下,您可能希望注入一个有点重的服务   实例化,但并不总是在对象中使用。例如,   想象你有一个NewsletterManager,你注入了一个邮件服务   进去。您的NewsletterManager上只有少数方法实际使用了   邮件,但即使你不需要它,邮件服务总是如此   实例化以构建您的NewsletterManager。

这是可修复的,还是使用延迟服务的缺点。

我虽然关于:

  • 接口类型提示可以解决这个问题吗? (有些工作,但我可以忍受它)
  • 不使用懒惰服务并接受“慢”的服务。申请(将是悲伤的消息)
  • 停止注入特定的存储库并返回注入实体管理器(感觉非常脏并且会破坏很多测试)

cookies for thoughs!

1 个答案:

答案 0 :(得分:3)

存储库服务定义中存在错误。将class: AppBundle\Entity\Company替换为class: AppBundle\Entity\CompanyRepository