惰性服务和类型提示的 Symfony2 DI
Symfony2 DI of lazy service and typehinting
在我们的应用程序中,我们将存储库定义为服务,如下例所示:
company.repository:
class: AppBundle\Entity\Company
factory: [@doctrine.orm.entity_manager, getRepository]
arguments:
- AppBundle\Entity\Company
这样我们就可以将它注入到我们只需要特定存储库而不是整个实体管理器的服务中。它更容易测试并降低了我们的服务耦合度。
例如:
company.service:
class: AppBundle\Services\CompanyService
arguments:
- @company.repository
构造函数类型暗示它的依赖关系:
<?php
use AppBundle\Entity\CompanyRepository
public function __construct(CompanyRepository $repo)
...
现在这个列表开始变大,我正在考虑将这些存储库定义为 lazy
以获得一些性能。
例如:
company.repository:
lazy: true
class: AppBundle\Entity\Company
factory: [@doctrine.orm.entity_manager, getRepository]
arguments:
- AppBundle\Entity\Company
乍一看,这似乎行得通。但经过一些测试后,我发现类型提示似乎已通过将这些服务定义为 lazy
而被破坏
将这些存储库定义为惰性后我收到的示例异常:
Catchable Fatal Error: Argument 1 passed to
AppBundle\EventListener\CompanyIdRequiredListener::__construct() must
be an instance of AppBundle\Entity\CompanyRepository, instance of
AppBundleEntityCompany_000000002d9713890000000167592edede1aa99e97f8c6a4a84b995db8a0c1e9
given
老实说,我对此异常感到惊讶,因为这似乎与官方 Symfony 文档描述的用例相似 here
In some cases, you may want to inject a service that is a bit heavy to
instantiate, but is not always used inside your object. For example,
imagine you have a NewsletterManager and you inject a mailer service
into it. Only a few methods on your NewsletterManager actually use the
mailer, but even when you don't need it, a mailer service is always
instantiated in order to construct your NewsletterManager.
这是可以解决的问题还是使用惰性服务的缺点。
我考虑过:
- 接口类型提示可能会解决这个问题? (有些工作,但我可以忍受)
- 不使用惰性服务并接受 'slower' 申请(这将是一个不幸的消息)
- 停止注入特定的存储库并return注入entitymanager(感觉真的很脏并且会破坏很多测试)
想法的 Cookie!
您在存储库服务定义中有错误。将 class: AppBundle\Entity\Company
替换为 class: AppBundle\Entity\CompanyRepository
.
在我们的应用程序中,我们将存储库定义为服务,如下例所示:
company.repository:
class: AppBundle\Entity\Company
factory: [@doctrine.orm.entity_manager, getRepository]
arguments:
- AppBundle\Entity\Company
这样我们就可以将它注入到我们只需要特定存储库而不是整个实体管理器的服务中。它更容易测试并降低了我们的服务耦合度。
例如:
company.service:
class: AppBundle\Services\CompanyService
arguments:
- @company.repository
构造函数类型暗示它的依赖关系:
<?php
use AppBundle\Entity\CompanyRepository
public function __construct(CompanyRepository $repo)
...
现在这个列表开始变大,我正在考虑将这些存储库定义为 lazy
以获得一些性能。
例如:
company.repository:
lazy: true
class: AppBundle\Entity\Company
factory: [@doctrine.orm.entity_manager, getRepository]
arguments:
- AppBundle\Entity\Company
乍一看,这似乎行得通。但经过一些测试后,我发现类型提示似乎已通过将这些服务定义为 lazy
将这些存储库定义为惰性后我收到的示例异常:
Catchable Fatal Error: Argument 1 passed to AppBundle\EventListener\CompanyIdRequiredListener::__construct() must be an instance of AppBundle\Entity\CompanyRepository, instance of AppBundleEntityCompany_000000002d9713890000000167592edede1aa99e97f8c6a4a84b995db8a0c1e9 given
老实说,我对此异常感到惊讶,因为这似乎与官方 Symfony 文档描述的用例相似 here
In some cases, you may want to inject a service that is a bit heavy to instantiate, but is not always used inside your object. For example, imagine you have a NewsletterManager and you inject a mailer service into it. Only a few methods on your NewsletterManager actually use the mailer, but even when you don't need it, a mailer service is always instantiated in order to construct your NewsletterManager.
这是可以解决的问题还是使用惰性服务的缺点。
我考虑过:
- 接口类型提示可能会解决这个问题? (有些工作,但我可以忍受)
- 不使用惰性服务并接受 'slower' 申请(这将是一个不幸的消息)
- 停止注入特定的存储库并return注入entitymanager(感觉真的很脏并且会破坏很多测试)
想法的 Cookie!
您在存储库服务定义中有错误。将 class: AppBundle\Entity\Company
替换为 class: AppBundle\Entity\CompanyRepository
.