我正在编写一个Symfony应用程序。意思是:该应用程序具有Symfony应用程序的结构,并使用Symfony的MVC(symfony/http-kernel
,symfony/routing
等(,但它应该尽可能独立于框架。因此,我使用的是PHP-DI,而不是框架的DI。
现在,我添加了symfony/event-dispatcher
组件,并为所有自定义事件注册了一个侦听器。
services.yaml
system.event_handler:
tags:
- { name: system.event_handler, event: general.user_message_received, method: handle }
- { name: system.event_handler, event: xxx.foo, method: handle }
- { name: system.event_handler, event: yyy.foo, method: handle }
- { name: system.event_handler, event: zzz.foo, method: handle }
system.event_handler
在我的 PHP-DI 依赖项文件中定义:
...
EventHandlerInterface::class => DIfactory(function(ContainerInterface $container) {
return new SystemEventHandler(
$container->get('process_handler.xxx'),
$container->get('process_handler.yyy'),
$container->get('process_handler.zzz')
);
}),
'system.event_handler' => DIget(EventHandlerInterface::class),
...
现在我收到一个错误:
运行时异常
"system.event_handler"的定义没有类。如果您打算 要在运行时动态注入此服务,请将其标记为 合成=真。如果这是仅由儿童使用的抽象定义 定义,请添加 abstract=true,否则指定一个类 摆脱此错误。
为什么?以这种速度使用别名有错吗?
好的,我已经将services.yaml
中的别名替换为事件处理程序的 FQCN:
AppProcessSystemEventHandler:
tags:
- { name: system.event_handler, event: general.user_message_received, method: handle }
- { name: system.event_handler, event: xxx.foo, method: handle }
- { name: system.event_handler, event: yyy.foo, method: handle }
- { name: system.event_handler, event: zzz.foo, method: handle }
不再有错误。但是事件处理程序仍然没有添加到EventDispatcher
中。
如何在 Symfony 4 中注册事件侦听器(在 PHP-DI 容器中定义(?
PHP-DI被称为Symfony容器的后备。因此,当一个条目没有在Symfony中定义时,它就会从PHP-DI中拉出来。但是,我从未尝试在两个容器中定义一个条目,从我的 POV(作为 PHP-DI 的维护者(来看,这不应该起作用。
由于您需要使用Symfony标签,最简单的解决方案是完全在Symfony的配置(而不是PHP-DI(中定义该特定服务。
另一个线索可能是尝试编写一个Symfony编译器传递来尝试完成这项工作,但我不知道这是否可行。如果您设法找到一个好的解决方案,请在 GitHub 存储库中报告,我们可以尝试集成它。