gpt4 book ai didi

Symfony 服务仅在方法调用后启动

转载 作者:行者123 更新时间:2023-12-02 13:18:30 25 4
gpt4 key购买 nike

我注意到 Symfony 服务仅在调用该服务中的方法时才会启动(执行构造函数)。如果您的服务只有构造函数而没有方法,这一点可能很重要。

例如:

class MyService {

public function __construct($someOtherService) {

$someOtherService->setFoo("bar");

}
}

// And of course put this service in services.yml

app.my_service:
class: AppBundle\...\MyService
arguments: [ app.some_other_service ]

在这种情况下,不会调用构造函数,因此不会调用 setFoo("bar")。为什么是这样?是否可以以某种方式强制启动服务,而不调用该服务上的(虚拟)方法?

我还尝试为 app.my_service 添加“lazy: false”,但这没有什么区别。

我使用的是 Symfony 2.8。

最佳答案

如果您的服务从未被使用过,则它们永远不会被实例化。为了强制实例化服务,当您想要获取服务(即kernel.request)并将该服务作为依赖项传递给监听器时,您可以 Hook 适合您的事件的任何类型的事件监听器。这将在容器生命周期内第一次触发事件时触发服务构造函数。

但我宁愿建议您回顾一下架构。仅使用构造函数提供服务是无意义的

此外,您可以在实例化 EventDispatcher 时实例化服务(只是因为它依赖于您的服务),而无需触发事件

监听器示例:

class ServiceInstantiatorListener
{
public function onRequest(KernelEvent $kernel)
{
return; //noop, just make sure it works
}

public function instantiate($service)
{
return $service; // noop again, just call to pass service container argument
}
}

yaml 配置:

services:
my_app.service_instantiator_listener:
class: My\App\ServiceInstantiatorListener
tags:
- { 'name': 'kernel_events', 'event': 'kernel.request', 'method':'onRequest' }
calls:
- [instantiate, ["@my_app.weird_service_one"]]
- [instantiate, ["@my_app.weird_service_two"]]

更进一步,您可以使用标签标记您的服务,并使用 MyAppBundleExtension 编译器 channel 动态配置调用

http://symfony.com/doc/current/service_container/tags.html#create-a-compiler-pass

我希望有更好的方法来强制实例化服务(即一些容器内部事件),但目前我还没有遇到我需要的情况。

关于Symfony 服务仅在方法调用后启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39812775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com