我正在编写一个Symfony应用程序。意味着:应用程序具有Symfony应用程序的结构,并使用Symfony的 M VC(symfony/http-kernel
,symfony/routing
等),但它应尽可能与框架无关。所以我没有使用框架的DI,而是使用PHP-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 => DI\factory(function(ContainerInterface $container) {
return new SystemEventHandler(
$container->get('process_handler.xxx'),
$container->get('process_handler.yyy'),
$container->get('process_handler.zzz')
);
}),
'system.event_handler' => DI\get(EventHandlerInterface::class),
...
现在我收到了一个错误:
的RuntimeException
“system.event_handler”的定义没有类。如果你打算 要在运行时动态注入此服务,请将其标记为 合成=真。如果这是儿童单独使用的抽象定义 定义,请添加abstract = true,否则指定一个类 摆脱这个错误。
为什么呢?以这种速度使用别名是错误的吗?
好的,我已经用我的事件处理程序的FQCN替换了services.yaml
中的别名:
App\Process\SystemEventHandler:
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容器中定义)?
答案 0 :(得分:0)
PHP-DI被称为Symfony容器的后备。因此,当Symfony中没有定义条目时,它将退出PHP-DI。但是我从来没有尝试在两个容器中定义一个条目,从我的POV(作为PHP-DI的维护者)这不应该起作用。
由于您需要使用Symfony标记,最简单的解决方案是完全在Symfony的配置(而不是PHP-DI)中定义该特定服务。
另一个主要可能是尝试编写Symfony编译器传递来尝试使其工作,但我不知道这是否可行。如果您设法找到一个好的解决方案,请在the GitHub repository中报告,我们可以尝试整合它。