Commit 843387f4 authored by Daniel Król's avatar Daniel Król

Support listenerResolvers

parent cc30b6df
#narrator\narrator-bundle
# narrator\narrator-bundle
[![Travis CI](https://travis-ci.org/mleko/narrator-bundle.svg?branch=master)](https://travis-ci.org/mleko/narrator-bundle)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/mleko/narrator-bundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/mleko/narrator-bundle/?branch=master)
[![Code Coverage](https://scrutinizer-ci.com/g/mleko/narrator-bundle/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/mleko/narrator-bundle/?branch=master)
##Installation
## Installation
Add project depdendency using [Composer](http://getcomposer.org/):
......@@ -35,7 +35,7 @@ class AppKernel extends Kernel
}
```
##Configure listeners
## Configure listeners
NarratorBundle loads listeners from dependency container.
To use service as a listener you only need to add tag marking service as listener.
......
......@@ -7,6 +7,10 @@
namespace Mleko\Narrator\Bundle\DependencyInjection\Compiler;
use Mleko\Narrator\Bundle\Listener\ListenerService;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class ListenerPass implements \Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface
{
......@@ -41,11 +45,18 @@ class ListenerPass implements \Symfony\Component\DependencyInjection\Compiler\Co
$this->registerListener($container, $eventName, $busName, $serviceId, $methodName);
}
private function registerListener(\Symfony\Component\DependencyInjection\ContainerBuilder $container, $busName, $emitterName, $listenerServiceId, $methodName)
private function registerListener(\Symfony\Component\DependencyInjection\ContainerBuilder $container, $eventName, $emitterName, $listenerServiceId, $methodName)
{
$emitterDefinition = $container->getDefinition('narrator.event_bus.' . $emitterName);
$listeners = $emitterDefinition->getArgument(1);
$listeners[$busName][] = ['serviceId' => $listenerServiceId, 'methodName' => $methodName];
$listeners[$eventName][] = new Definition(
ListenerService::class,
[
$listenerServiceId,
new Reference("service_container"),
$methodName
]
);
$emitterDefinition->replaceArgument(1, $listeners);
}
}
......@@ -23,9 +23,28 @@ class Configuration implements ConfigurationInterface
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('narrator');
// Here you should define the parameters that are allowed to
// configure your bundle. See the documentation linked above for
// more information on that topic.
$rootNode
->children()
->arrayNode('event_bus')
->defaultValue(['default' => ['resolver' => ['type' => 'name', "name_extractor" => "narrator.name_extractor.class_name"]]])
->requiresAtLeastOneElement()
->useAttributeAsKey('name')
->prototype("array")
->children()
->arrayNode('resolver')
->children()
->enumNode('type')
->values(['name', 'instanceof', 'service'])
->isRequired()
->end()
->scalarNode('name_extractor')
->defaultValue("narrator.name_extractor.class_name")
->end()
->scalarNode('service_id')
->end()
->end()
->end()
->end();
return $treeBuilder;
}
......
<?php
namespace Mleko\Narrator\Bundle\DependencyInjection\Configuration;
use Mleko\Narrator\BasicEventBus;
use Mleko\Narrator\ListenerResolver\InstanceOfResolver;
use Mleko\Narrator\ListenerResolver\NameBasedResolver;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class EventBusConfiguration
{
/**
* @param $buses
* @param ContainerBuilder $container
*/
public function configureEventBus($buses, ContainerBuilder $container)
{
foreach ($buses as $busName => $busConfig) {
$resolverServiceId = "narrator.event_bus.$busName.resolver";
$resolverConfig = isset($busConfig['resolver']) ? $busConfig['resolver'] : [];
$container->setDefinition(
$resolverServiceId,
$this->buildResolver($resolverConfig)
);
$container->setDefinition(
"narrator.event_bus.$busName",
new Definition(
BasicEventBus::class,
[
new Reference($resolverServiceId),
[]
]
)
);
}
}
private function buildResolver($resolverConfig)
{
$resolverType = isset($resolverConfig['type']) ? $resolverConfig['type'] : 'name';
switch ($resolverType) {
case 'instanceof':
return new Definition(InstanceOfResolver::class);
case 'service':
return new Reference($resolverType['service_id']);
default:
$nameExtractorId = isset($resolverConfig['name_extractor']) ? $resolverConfig['name_extractor'] : "narrator.name_extractor.class_name";
return new Definition(
NameBasedResolver::class,
[new Reference($nameExtractorId)]
);
}
}
}
......@@ -5,6 +5,7 @@
namespace Mleko\Narrator\Bundle\DependencyInjection;
use Mleko\Narrator\Bundle\DependencyInjection\Configuration\EventBusConfiguration;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
......@@ -25,6 +26,8 @@ class NarratorExtension extends Extension
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
(new EventBusConfiguration())->configureEventBus($config['event_bus'], $container);
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.xml');
}
......
<?php
/**
* @package narrator-bundle
*/
namespace Mleko\Narrator\Bundle;
use Mleko\Narrator\EventNameExtractor;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EventBusFactory
{
/**
* @var ContainerInterface
*/
private $container;
/**
* EventBusFactory constructor.
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @param EventNameExtractor $nameExtractor
* @param $listenerDefinitions
* @return \Mleko\Narrator\BasicEventBus
*/
public function createEventBus(EventNameExtractor $nameExtractor, $listenerDefinitions)
{
$listeners = [];
foreach ($listenerDefinitions as $eventName => $listenerDefinition) {
foreach ($listenerDefinition as $listenerData) {
$listeners[$eventName][] = new Listener\ListenerService($listenerData['serviceId'], $this->container, $listenerData['methodName']);
}
}
return new \Mleko\Narrator\BasicEventBus($nameExtractor, $listeners);
}
}
......@@ -6,16 +6,7 @@
<services>
<service id="narrator.event_bus" alias="narrator.event_bus.default"/>
<service id="narrator.event_bus.default" class="Mleko\Narrator\BasicEventBus">
<factory service="narrator.event_bus_factory" method="createEventBus"/>
<argument type="service" id="narrator.name_extractor.class_name"/>
<argument type="collection"/>
</service>
<service id="narrator.name_extractor.class_name" class="Mleko\Narrator\EventNameExtractor\ClassNameExtractor"/>
<service id="narrator.event_bus_factory" class="Mleko\Narrator\Bundle\EventBusFactory">
<argument type="service" id="service_container"/>
</service>
</services>
</container>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment