我有一个配置值,其中我为一个Doctrine事件定义了一个事件侦听器,并且我正在为侦听器中所需的服务使用DI。
$services->set(ExamplePrePersistListener::class)
->tag('doctrine.event_listener', ['event' => 'prePersist', 'priority' => 500]);
这个侦听器在http请求期间触发,因此我拥有的依赖项之一是服务(UserBuilder),它从会话中获取登录用户,但现在我需要在cli请求期间触发同一个侦听器,因此我的想法是重构侦听器,以通过接口获得依赖关系(UserBuilderInterface),这样我就可以定义在不同的请求中发送哪个实现。我将以两个实现HttpUserBuilder,CliUserBuilder结束。
我的问题是我如何告诉Symfony根据请求发送每个实现?我如何在配置文件中设置侦听器,以便能够决定给定的实现?
1条答案
按热度按时间6uxekuva1#
正如@Cerad在评论中建议的那样,我决定执行一个简单的if check
if ('cli' === PHP_SAPI)
来判断我是否从cli运行。虽然这解决了我的依赖性问题,比如我的值对象中的依赖性,但这并没有完全解决Doctrine侦听器问题中提出的问题,但我修改了我的初始想法以适应这一点。Doctrine侦听器的问题是我不知道在运行时发送哪个依赖项,因此一个选择是在services.php配置文件中检查if(并通过args方法发送),但这样做感觉有点笨拙,主要是因为我想迁移到yaml配置。另一个选项是基于配置值将其设置为setter依赖项(is_cli或类似的东西),但是当从CLI运行时,我需要始终设置这个参数。
所以我使用了当前的UserBuilder,并使用@Cerad提到的服务定位器。无论如何,我使用的是Builder模式,因此构建器类可以决定我是否使用CLI,而不是使用两个单独的构建器类(CliUserBuilder和HttpUserBuilder),然后是第三个位置,它决定发送哪一个。第二个位置可能是更好的关注点分离,但我不想仅仅为了它而添加额外的配置层。
我的UserBuilder类如下所示:
据我所知,服务定位器只创建这些依赖项的代理,因此它们在被调用之前不会被示例化,这意味着如果我在CLI中,那么RequestStack永远不会被调用。
这也允许我进行最小的重构,所以我想我可以接受它。