【问题标题】:Symfony 4: Statically get container in helper classSymfony 4:静态获取辅助类中的容器
【发布时间】:2018-11-07 07:12:41
【问题描述】:

我正在为 symfony 开发一个类似记录的活动系统,但遇到了一个问题。

我在 symfony 中有一个不是服务的助手类,我也不希望它成为一个服务。这个类有一个名为 container 的静态属性和一个设置它的静态方法。现在的问题是,什么时候调用这个静态方法来设置容器?

我已经尝试过捆绑扩展、编译器通过,但都没有成功。 (主要是因为它们必须是服务,当我将其作为服务并稍后扩展它时,它会跳过编译器传递。)

如果有人需要任何进一步的信息,请告诉我,并提前致谢!

【问题讨论】:

  • 你能解释一下它不是服务的意思吗?如果我对您的理解正确,您希望将服务注入容器以使其可用,即您想要一个合成服务,就 Symfony DI 而言。见:symfony.com/doc/current/service_container/…
  • 不。实际上我根本不是这么说的。我想要服务容器 INSIDE 的这个助手类是不是服务。所以,它只是一个普通的类,带有一个静态方法:public static function set(ContainerInterface $container) { self::$container = $container; }
  • 我提供了一个更详尽的答案,希望更清楚。合成服务方法是 Kernel 类用来创建容器,使其作为 Kernel 的一部分可用,但也将自身注入到容器中以使其像服务一样可用。看来您对该术语的定义与 Symfony 所称的服务不同。在任何情况下,展示您如何创建此帮助程序或计划创建它以及您如何/在何处使用它以及其中的容器可能有助于更好地了解您的问题并让我们提供更好的解决方案。
  • 如果你坚持做这种静态的东西,那么去掉setContainer方法,让你的类直接使用全局$kernel->getContainer方法()访问容器。但是你走错了路,只会遇到更多的问题。特别是在 S4 中,容器服务默认是私有的,不能通过容器直接访问。
  • 好吧,我不打算将外观构建到 symfony 中,只是活动记录模型。而且由于我不会在实体上公开容器引用,所以我看不出它是一种反模式。

标签: symfony activerecord service static containers


【解决方案1】:

如果你想将容器注入到帮助器中,即调用Helper::set($ontainer),你必须在编译容器可用时进行。 Extension 和 Compiler Pass 都在编译前修改容器,因此可能不是正确的位置,除非您想将帮助程序作为服务注入容器并引用容器,就像下面的方法概述一样。

您可以在创建容器的内核中调用 Setter 方法,或者在构建容器时加载的 Controller 中调用 Setter 方法,并且 - 当您扩展 Controller-base 类时,可以访问容器。不过,我认为这不是一个好主意,因为您永远无法确定何时/是否调用了该方法以及其中包含什么容器。此外,当使用新的AbstractController 基类时,您无法访问完整的容器,只能访问控制器所需特定服务的服务定位器。

将其配置为services.yaml 中的服务时,您可以使用calls or setter injection 通过引用@container 来注入容器服务。我也不推荐这样做,但考虑到您的要求,我认为这是两害相权取其轻。

【讨论】:

  • 我想过控制器的想法,但这基本上属于我现在面临的同样问题。我确实将助手类配置为服务,发生的事情是,在编译器为我注入容器之前,我必须先注入它(不必使用它)。另外,在服务中使用它们怎么样?扩展控制器不会帮助你。另外,你可以在不使用全局的情况下访问包内的内核吗?
  • 您的助手不应依赖容器或内核。你可以让内核全局化,但我只认为这是一种将容器引入遗留应用程序的方法,该应用程序将过渡到不再需要这个全局内核的 Symfony。如果您为/在 Symfony 中构建某些东西,我看不到您想做的事情的用途。如果你构建独立于 Symfony 的东西,我认为依赖于特定于 Symfony 的东西就更没用了。
  • 话虽如此,我仍然只知道你想做什么,但不知道为什么。您必须为您的问题添加更多详细信息,以便我为您的特定用例提供真正有用的答案。
  • 我提到了 Active Records 模式。因此,您可以扩展ActiveRecord 类,该类又扩展了前面提到的助手类。然后ActiveRecord 可以访问所有存储库功能,并能够执行findOneBy 等内容。这使得:Product::findOneBy(['foo' => 'bar']); 和类似的事情成为可能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多