我正在构建一个非常依赖第三方API的网站,所以我认为将API包装器打包为服务是有意义的,但是我开始找到有用的实例。在控制器之外访问它,例如在实体存储库中。 与此相关的是能够访问控制器之外的配置值(例如在实体存储库中)也是有用的。
任何人都可以告诉我这是否可行,如果没有,是否有建议的方法来做这种事情?
感谢您的帮助
答案 0 :(得分:74)
Symfony发行版在很大程度上依赖于依赖注入。这意味着通常,依赖项通过构造函数,setter或其他方式(如属性反射)直接注入到对象中。然后,您的API包装器服务是应用程序的其他对象的依赖项。
话虽如此,在实体存储库的构造函数中注入此服务会相当困难,因为它已经需要一些其他参数,我认为由于我们为实体请求存储库的方式而无法注入它们
您可以做的是创建另一项服务,该服务将负责您在实体存储库中执行的工作。这样,您就可以注入实体管理器,它将用于检索实体存储库,自定义服务以及另一个包含配置值的服务(还有其他方法可以共享配置值)。
在我的用例中,我使用Facebook帮助程序服务来包装Facebook API调用。然后将此服务注入我需要的地方。我的实体存储库只负责执行数据库调用,因此它只接收所需的参数而不是整个依赖项。因此,它不会接收帮助程序,而只接收执行请求所需的参数,例如,Facebook用户ID。在我看来,这是实现它的方法,因为我认为实体存储库不应该依赖于这样的辅助对象。
这是一个使用YAML作为配置的小例子:
# app/config/config.yml
services:
yourapp.configuration_container:
class: Application/AcmeBundle/Common/ConfigurationContainer
# You could inject configurations here
yourapp.api_wrapper:
class: Application/AcmeBundle/Service/ApiWrapperService
# Inject other arguments if needed and update constructor in consequence
yourapp.data_access:
class: Application/AcmeBundle/Data/Access/DatabaseAccessService
arguments:
entityManager: "@doctrine.orm.entity_manager"
apiWrapperService: "@yourapp.api_wrapper"
configuration: "@yourapp.configuration_container"
# Application/AcmeBundle/Common/ConfigurationContainer.php
public ConfigurationContainer
{
public function __construct()
{
// Initialize your configuration values or inject them in the constructor
}
}
# Application/AcmeBundle/Service/ApiWrapperService.php
public ApiWrapperService
{
public function __construct()
{
// Do some stuff
}
}
# Application/AcmeBundle/Data/Access/DatabaseAccessService.php
public DatabaseAccessService
{
public function __construct(EntityManager $entityManager, ApiWrapperService $apiWrapperService, ConfigurationContainer $configuration)
{
...
}
}
config.yml文件中的at符号(@)表示Symfony应该注入另一个服务,在at符号后面定义了id,而不是简单的字符串。对于配置值,正如我之前所说,还有其他方法可以实现相同的目标,例如使用参数或bundle扩展。使用bundle扩展,你可以直接在config.yml中定义配置值,你的bundle会读取它们。
总之,这应该为您提供注入服务的一般概念。这里有一小部分关于这个主题的文档。很多链接使用XML服务定义而不是YAML定义,但您应该能够很容易地理解它们。
请注意,我给出的配置适用于Symfony2的Beta1。我还没有更新到Beta2,所以可能有些东西不能用于Beta2版本。
我希望这可以帮助您定义问题的最终解决方案。如果您需要澄清或其他任何内容,请随时提出其他问题。
此致 马特
答案 1 :(得分:0)
我会将这种行为包装在Symfony服务中(比如管理器)。 我不会将任何参数或逻辑注入实体存储库,因为它们应主要用于使用对象管理器查询获取数据。 我会将逻辑放在服务中,如果服务需要数据库访问,它将调用实体存储库来获取数据。