如何使用Symfony2访问控制器之外的服务?

我正在build立一个网站,很大程度上依赖于第三方API,所以我认为将API封装器作为一个服务来打包是有意义的,但是我开始发现有可能访问它的实例在控制器之外,比如在实体库中。 与此相关的是,能够访问控制器之外的configuration值(例如在实体存储库中)将是有用的。

任何人都可以告诉我,如果这是可能的,如果不是有一个build议的做法做这种事情?

感谢您的帮助

Symfony发行版很大程度上依赖于dependency injection。 这意味着通常,依赖关系通过构造函数,设置器或其他方式(比如属性的reflection)直接注入到对象中。 您的API包装服务是您的应用程序的其他对象的依赖项。

也就是说,将这个服务注入一个实体库的构造函数是相当困难的,因为它已经需要一些其他的参数了,我认为不可能注入这个服务,因为我们要求一个实体的存储库。

你可以做的是创build另一个服务,负责做你将要在实体库中做的工作。 这样,您将能够注入将用于检索实体存储库的实体pipe理器,自定义服务以及保存configuration值(还有其他方法来共享configuration值)的另一个服务。

在我的使用案例中,我使用了一个包装Facebook API调用的Facebook帮助器服务。 这个服务然后被注入我需要的地方。 我的实体存储库只负责进行数据库调用,所以它只接收它需要的参数,而不是整个依赖。 因此,它将不会收到助手,而只会收到请求所需的参数,例如Facebook用户标识。 在我看来,这是做的方法,因为我认为实体库不应该有这样的辅助对象的依赖。

这里有一个使用YAML作为configuration的小例子:

# 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,而不是一个简单的string。 正如我之前所说的,对于configuration值来说,还有其他方法可以像使用参数或bundle扩展一样实现相同的目标。 使用bundle扩展,你可以直接在config.yml中定义configuration值,你的bundle会读取它们。

总之,这应该给你注入服务的总体思路。 这里有一个关于这个主题的文档的小清单。 链接的许多使用XML服务定义,而不是YAML定义,但你应该能够很容易地理解它们。

  1. Symfony官方DI
  2. Fabien Potencier在DI上的文章
  3. Richard Miller在DI上的文章 (在他的博客中查看其他DI文章)

请注意,我给的configuration是为Symfony2的Beta1工作。 我还没有更新到Beta2,所以可能会有一些东西,因为他们在Beta2版本不工作。

我希望这会帮助你为你的问题定义一个最终的解决scheme。 不要犹豫,如果你想澄清或其他任何问题提出其他问题。

问候,马特

我会把这种行为包装在一个Symfony服务中(像一个经理)。 我不会将任何参数或逻辑注入实体存储库,因为它们主要用于使用对象pipe理器查询来获取数据。 我将把逻辑放在服务中,如果服务需要数据库访问,它将调用实体存储库来获取数据。