延迟服务和类型提示的Symfony2 DI

延迟服务和类型提示的Symfony2 DI,symfony,repository,lazy-loading,Symfony,Repository,Lazy Loading,在我们的应用程序中,我们将存储库定义为服务,如以下示例所示: company.repository: class: AppBundle\Entity\Company factory: [@doctrine.orm.entity_manager, getRepository] arguments: - AppBundle\Entity\Company 因此,我们可以将其注入到只需要特定存储库而不需要整个实体管理器的服务中。它更易于测试,并使我们的服务耦合性

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

company.repository:
    class: AppBundle\Entity\Company
    factory: [@doctrine.orm.entity_manager, getRepository]
    arguments:
        - AppBundle\Entity\Company
因此,我们可以将其注入到只需要特定存储库而不需要整个实体管理器的服务中。它更易于测试,并使我们的服务耦合性降低

例如:

构造函数类型暗示其依赖项:

<?php

use AppBundle\Entity\CompanyRepository

public function __construct(CompanyRepository $repo)
...
乍一看,这似乎奏效了。但是在一些测试之后,我发现通过将这些服务定义为
lazy

我在将这些存储库定义为惰性后收到的一个异常示例:

可捕获致命错误:参数1传递给 AppBundle\EventListener\CompanyIdRequiredListener::\uu构造()必须 是AppBundle\Entity\CompanyRepository的实例,是的实例 AppBundleEntityCompany_u000000002D97138900000167592EDE1AA99E97F8C6A4A84B995DB8A0C1E9 给定

我真的对这个异常感到惊讶,因为这似乎是一个由官方Symfony文档描述的simlar用例

在某些情况下,您可能希望注入一个对您来说有点沉重的服务 实例化,但并不总是在对象内部使用。例如 假设你有一个时事通讯管理器,你注入了一个邮件服务 我喜欢它。您的新闻稿管理器上只有少数几个方法实际使用 mailer,但即使在你不需要它的时候,mailer服务也总是有用的 实例化以构建您的新闻稿管理器

这是可修复的还是使用惰性服务的缺点

我想:

  • 接口类型暗示可以解决这个问题吗?(这是一些工作,但我能接受)
  • 不使用惰性服务并接受“较慢”的应用程序(这将是一个令人伤心的消息)
  • 停止注入特定的存储库,返回注入entitymanager(感觉非常脏,会破坏很多测试)

给思想的饼干

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

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

我没有使用惰性存储库服务。如果删除typehint是否有效?我没有使用惰性存储库服务。如果你删除字体提示行吗?天哪,即使我读了100遍,我也会错过这个。我现在感觉好笨,谢谢!有趣。通常情况下,类:在使用工厂时并不重要。但我想对于惰性服务,该类用于生成代理。想知道使用惰性存储库是否真的提高了性能。代理本身增加了大量的开销,我并不认为存储库都很重。但谁知道呢,使用apache bench进行的一些快速测试使avarage的性能提高了+/-150-200毫秒。(这只是一个api端点)。看起来很有希望,但我需要做更多的测试才能得出一个可靠的结论。哦,天哪,即使我读了100遍,我也会错过这个。我现在感觉好笨,谢谢!有趣。通常情况下,类:在使用工厂时并不重要。但我想对于惰性服务,该类用于生成代理。想知道使用惰性存储库是否真的提高了性能。代理本身增加了大量的开销,我并不认为存储库都很重。但谁知道呢,使用apache bench进行的一些快速测试使avarage的性能提高了+/-150-200毫秒。(这只是一个api端点)。看起来很有希望,但我需要做更多的测试才能得出一个可靠的结论。
<?php

use AppBundle\Entity\CompanyRepository

public function __construct(CompanyRepository $repo)
...
company.repository:
    lazy: true
    class: AppBundle\Entity\Company
    factory: [@doctrine.orm.entity_manager, getRepository]
    arguments:
        - AppBundle\Entity\Company