Symfony EventDispatcher服务标签不在Symfony App内

时间:2017-07-10 04:25:43

标签: php symfony symfony-2.8 event-dispatching

在Symfony应用程序中使用Symfony 2.8事件调度程序和容器组件

来自我的bootstrap / kernel文件:

$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文件中的标签

1 个答案:

答案 0 :(得分:2)

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

enter image description here

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');