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

如何使用Symfony2访问控制器外部的服务?,symfony,service,Symfony,Service,我正在构建一个非常依赖第三方API的站点,因此我认为将API包装器打包为服务是有意义的,但是我开始发现在控制器之外(例如在实体存储库中)访问API包装器是有用的。 与此相关的另一点是,能够在控制器之外(同样是在实体存储库中)访问配置值将非常有用 有人能告诉我这是否可能,如果没有,有没有一个建议的方法来做这类事情 感谢您的帮助Symfony发行版严重依赖依赖依赖注入。这意味着,依赖项通常通过构造函数、setter或其他方式(如属性上的反射)直接注入到对象中。然后,API包装器服务是应用程序其他对象

我正在构建一个非常依赖第三方API的站点,因此我认为将API包装器打包为服务是有意义的,但是我开始发现在控制器之外(例如在实体存储库中)访问API包装器是有用的。 与此相关的另一点是,能够在控制器之外(同样是在实体存储库中)访问配置值将非常有用

有人能告诉我这是否可能,如果没有,有没有一个建议的方法来做这类事情


感谢您的帮助

Symfony发行版严重依赖依赖依赖注入。这意味着,依赖项通常通过构造函数、setter或其他方式(如属性上的反射)直接注入到对象中。然后,API包装器服务是应用程序其他对象的依赖项

话虽如此,将此服务注入实体存储库的构造函数将是相当困难的,因为它已经需要一些其他参数,而且我认为由于我们请求存储库获取实体的方式,不可能注入这些参数

您可以做的是创建另一个服务,该服务将负责完成您将要在实体存储库中完成的工作。通过这种方式,您将能够注入实体管理器,该管理器将用于检索实体存储库、自定义服务以及保存配置值的另一个服务(有其他方式共享配置值)

在我的用例中,我使用了一个封装Facebook API调用的Facebook助手服务。然后在我需要的地方注入此服务。我的实体存储库只负责执行数据库调用,因此它只接收它需要的参数,而不是整个依赖项。因此,它将不接收帮助程序,而只接收执行请求所需的参数,例如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定义,但是您应该能够非常容易地理解它们

  • (在他的博客中查看其他DI文章)
  • 请注意,我给出的配置适用于Symfony2的Beta1。我还没有更新到Beta2,所以可能有一些东西不能像Beta2版本那样工作

    我希望这将帮助您确定问题的最终解决方案。如果你想要澄清或其他任何事情,不要犹豫问其他问题

    问候,,
    马特

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

    这是巨大的帮助,我已经将API服务注入到数据库服务中,这很好。我仍然不清楚如何最好地进行配置。如果我能解释一下我想做什么可能是最好的。我正在构建一个可以跨多个域工作的站点,每个站点都将作为一个具有自己的yaml配置文件的环境存在。在配置文件中会有一个站点id,例如,我希望能够调用getUsers(),并从配置中获取站点id,并自动向查询中添加“where site_id=x”。这是可能的还是我应该将id作为参数传递?刚刚意识到您链接到的Symfony文章解释了如何执行此操作,再次感谢您的帮助。这让我紧张了好几天,所以有了解决方案真是太好了。很高兴这有帮助,而且你现在有了解决问题的方法:)事实上,我链接的文章更明确地介绍了如何使用参数和类似的东西。祝你工作顺利。注意复制代码!它包含
    \u构造函数
    而不是
    \u构造函数
    ,顺便说一句,答案是+1!