zendframework/zf2 — pull request #6323 by ronan-gloo (2014-05-24 16:55:47+00:00)
Title: Move Event creation into dedicated resolvers

### How it's supposed to work

When triggering a event from EventManager, if no EventInterface implementation is given in arguments, the EventManager rely on the eventClass property in order to create an event object.

This PR is an attempt to have more granularity on what event must be created, according arguments of `trigger()` method.

At this point, the EventManager request its resolver (through `get()` method) in order to get an event instance. A basic illustration is given with the DefaultResolver, which reproduce the original behavior.

Lets illustrate with a custom resolver that only accept some set of events to be triggered:

```php
class WhiteListProvider implements ProviderInterface
{
protected $allowedEvents = ['event1', 'event2']

public function get($eventName, $context = null, $parameters = [])
{
if (! in_array($eventName, $this->allowedEvents) {
throw new Exception('Cannot trigger arbitrary named events');
}

return new Event($eventName, $context, $parameters);
}
}
```

Each time you'll attempt to trigger a non allowed event by its name, an exception will be thrown.

To add the provider:

```php
$eventManager->setEventProvider($provider);
```

Another interesting usage would be to create a specific event instance according the requested name:

```php
class ErrorProvider implements ProviderInterface
{
public function get($eventName, $context = null, $parameters = [])
{
if (fnmatch('*.[error][failed]', $eventName)) {
$event = new ErrorEvent($eventName, $context);
$event->setException($parameters['exception']);

return $event;
}
}
}
```

Additionally, a ProviderAggregator is shipped with this PR, that allow you to hold multiples event providers strategies. The ProviderAggregator will return the first EventInterface found when `get` is invoked
Providers are stored in a PriorityQueue, in order to allow you to define providers priorities:

```php

$aggregator = new ProviderAggregate;
$aggregator->addProvider($provider1, -10);
$aggregator->addProvider($provider2, 10);
```

Also, (but i'm not sure if it must be shipped with ZF), there is a PluginManager, which can be used to create a Provider that rely on registered events:

```php
class ServiceAwareProvider implements ProviderInterface, ServiceLocatorAwareInterface
{
public function get($eventName, $context = null, $parameters = [])
{
if ($this->getServiceLocator()->has($eventName) {
$event = $this->getServiceLocator()->get($eventName);
}
}
}
```

As far as i know, there is no BC breaks: The EventManager instantiate the DefaultProvider if none is set.
About performances, the introduction of the DefaultProvider instead of previous workflow is, of course, a little bit slower (~ +7% for 10000 triggers, with PHP 5.5)