1

我正在编写一个 Symfony 应用程序。含义:应用程序具有 Symfony 应用程序的结构并使用 Symfony 的M VC(symfony/http-kernelsymfony/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_handlerPHP-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),
...

现在我收到一个错误:

运行时异常

“system.event_handler”的定义没有类。如果您打算在运行时动态注入此服务,请将其标记为 synthet=true。如果这是一个仅由子定义使用的抽象定义,请添加abstract=true,否则指定一个类以消除此错误。

为什么?以这种速度使用别名是错误的吗?

好的,我已经用services.yaml我的事件处理程序的 FQCN 替换了别名:

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 容器中定义)?

4

1 回答 1

0

PHP-DI 被称为 Symfony 容器的后备。因此,当一个条目没有在 Symfony 中定义时,它就会从 PHP-DI 中拉出。但是,我从未尝试在两个容器中定义条目,从我的 POV(作为 PHP-DI 的维护者)来看,这不应该起作用。

由于您需要使用 Symfony 标签,最简单的解决方案是完全在 Symfony 的配置(不是 PHP-DI)中定义该特定服务。

另一个线索可能是尝试编写一个 Symfony 编译器通道来尝试使其工作,但我不知道这是否可行。如果您设法找到一个好的解决方案,请在GitHub 存储库中报告它,我们可以尝试集成它。

于 2018-04-30T06:45:14.293 回答