【问题标题】:Symfony EventDispatcher Service Tags Not Inside Symfony AppSymfony EventDispatcher 服务标签不在 Symfony 应用程序中
【发布时间】:2017-07-10 04:25:42
【问题描述】:

在 Symfony 应用程序中使用 Symfony 2.8 Event Dispatcher 和 Container 组件

来自我的引导程序/内核文件:

$this->container = new ContainerBuilder(new ParameterBag());
$this->getContainer()->addCompilerPass(new RegisterListenersPass());
$this->getContainer()->register('event_dispatcher', EventDispatcher::class);
$this->loadServiceConfig(); // See below for reference

/** @var EventDispatcher $ed */
$ed = $this->getContainer()->get('event_dispatcher');
// The next line works
$ed->addSubscriber(new SampleSubscriber());

...

private function loadServiceConfig()
{
    $loader = new YamlFileLoader($this->container, new FileLocator(__DIR__);
    $loader->load('config/services.yml');
}

来自config/services.yml

services:
    sample_subscriber:
        class: Sample\Event\SampleSubscriber
        public: true
        tags:
            - { name: kernel.event_subscriber }

手动订阅有效,但我希望事件会自动附加给定 yaml 文件中的标签

【问题讨论】:

  • 您至少需要“编译”容器才能启动 RegisterListenerPass()。从未尝试在框架之外使用编译器传递,因此无法提供任何细节。
  • 添加了 compile() 调用,但仍然没有骰子。我会进一步调查。
  • 创建了一个接近你的独立示例,我验证它确实有效。 (如果您想参考):github.com/simshaun/so-45003754

标签: php symfony symfony-2.8 event-dispatching


【解决方案1】:

我创建了一个独立的 repo,展示了如何设置容器、事件调度程序和 RegisterListenersPass:

https://github.com/simshaun/so-45003754

Symfony 2.8 需要 ContainerAwareEventDispatcher 才能使 RegisterListenersPass 起作用。

这是设置/接线的重点:

<?php

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

require __DIR__.'/vendor/autoload.php';


class App
{
    protected $container;

    public function __construct()
    {
        $builder = new ContainerBuilder(new ParameterBag());
        $builder->addCompilerPass(new RegisterListenersPass());

        $definition = new Definition(ContainerAwareEventDispatcher::class, [new Reference('service_container')]);
        $builder->setDefinition('event_dispatcher', $definition);

        $loader = new YamlFileLoader($builder, new FileLocator(__DIR__));
        $loader->load('services.yml');

        $builder->compile();
        $this->container = $builder;
    }

    public function getEventDispatcher(): EventDispatcherInterface
    {
        return $this->container->get('event_dispatcher');
    }
}


$app = new App();
$ed = $app->getEventDispatcher();
$ed->dispatch('my.event');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多