简体   繁体   中英

Symfony EventDispatcher Service Tags Not Inside Symfony App

Using Symfony 2.8 Event Dispatcher and Container components not inside a Symfony App

From my bootstrap/kernel file:

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

From config/services.yml :

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

The manual subscription works, but I would expect the event to automatically attach given the tags from the yaml file

I created a standalone repo showing how to set up the container, event dispatcher, and the RegisterListenersPass:

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

Symfony 2.8 needs a ContainerAwareEventDispatcher for the RegisterListenersPass to function.

Here's the meat of the setup/wiring:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM