Quantcast

Shared Event Manager

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Shared Event Manager

Gregory
By default the MVC Application Event Manager is not a shared service
object and it has its own Shared Event Manager. However this
particular Shared Event Manager is not shared with other Event
Managers and by default all the other Event Managers will fall back to
using the Static Event Manager as their Shared Event Manager.

One scenario is that you have two independently configured Service
Managers, if the same component (not instance) ends up utilizing the
(static) shared event manager, then, to me, suggests that developer
has to figure out and ensure that the listeners invoked via one
service object will not affect/invoke the listeners via the other
Service Manager.... Isn't this way to confusing?

Another scenario is that within the bootstrap of a module, then it is
not possible to attach a listener to another Event Manager whose
identifier is not 'application'. e.g

$em = $event->getApplication()->events()->getSharedManager();

$em->attach('member', 'addMember', function() {
            var_dump(__LINE__.' '.__FILE__);
});


The above means that the Member Service Component would have its own
Event Manager and by default using the Static Event Manager as the
shared event manager.

But the above will not work, because the MVC Application Event Manager
does not use the same shared event manager as the other event
managers. Which means having to changing the identifier to
'application' (or injecting the MVC Application Shared Event Manager
into all the other Event Managers, etc).


$em = $event->getApplication()->events()->getSharedManager();

$em->attach('application', 'addMember', function() {
            var_dump(__LINE__.' '.__FILE__);
});


However the latter above means that the Member Service Component must
then use the MVC Application Event Manager.

But setting $shared = array('EventManager' => true) bombs out within a
nested loop (related to ControllerLoader and the index Controller).

I think the Shared Event Manager should be just that, one by default
that is shared by all Event Managers and is not static but always
injected. This I think suggests getting it from the Service Manager
and automatically injecting via say a
SharedEventManagerAwareInterface.

I think that it should be highly recommended not to use class names
etc as identifiers, but use aliases instead e.g. 'application'.

If the Shared Event Managers do end up playing more nicely together
(e.g the MVC Application Shared Event Manager is the same one that the
other Event Managers use), then it might be worth considering removing
the 'identifier' completely and just have unique event names (this
could assume that an Event Manager should be aware of all the events
that it supports?). Another reason supporting this is, if the MVC
Application Event Manager is shared by all, then the identifier param
in its Shared Event Manager becomes redundant?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Shared Event Manager

weierophinney
Administrator
-- Greg <[hidden email]> wrote
(on Saturday, 30 June 2012, 01:30 PM -0500):
> By default the MVC Application Event Manager is not a shared service
> object and it has its own Shared Event Manager. However this
> particular Shared Event Manager is not shared with other Event
> Managers and by default all the other Event Managers will fall back to
> using the Static Event Manager as their Shared Event Manager.

Wrong.

If you use the ServiceManager, and use the EventManager factory, a
single instance of SharedEventManager is injected into each EventManager
instance. The fallback to the StaticEventManager should only happen
if you instantiate an EM instance manually and do not perform the
injeciton.

Basically, the suggestion you make later in this email is actually
already what is being done: a single SharedEventManager instance is
injected into every EventManager instance, and each component gets a
separate EventManager instance.

Please look at Zend\Mvc\Service\EventManagerFactory for details on how
the shared version of the SharedEventManager is implemented, and the
various factories in that namespace to see how each seeds components
with an EventManager pulled from that factory. The
ServiceManagerConfiguration class in that same namespace marks the
EventManager factory as unshared, which is how we can get discrete
instances of the EM into the various components that require one.

If you are manually instantiating an object that composes an EM
instance, if you have an EM already available, it's very easy to inject
the shared manager:

    $shared = $this->getEventManager()->getSharedManager();
    $component = new Some\Component();
    $component->getEventManager()->setSharedManager($shared);

If you don't do this, yes, you'll fall back to the StaticEventManager.
However, in most cases, you likely will be using the ServiceManager for
all dependencies. In such cases, your factories will look like this:

    function ($sm) {
        $component = new Some\Component();
        $component->setEventManager($sm->get('EventManager');
        return $component;
    }

This ensures all is wired correcly, and the SharedEventManager is
correctly injected.

<snip>

> I think that it should be highly recommended not to use class names
> etc as identifiers, but use aliases instead e.g. 'application'.

As for the named contexts the SharedEventManager uses, we decided on
class names and interface names as the typical context names, as this
makes it easier to know what EM instances are listening to what (just
look what object it's composed into). We chose not to use aliases, as
aliases are much, much harder to document, and require documentation to
understand what they refer to (class names and interface names are
self-explanatory and thus self-documenting).

> If the Shared Event Managers do end up playing more nicely together
> (e.g the MVC Application Shared Event Manager is the same one that the
> other Event Managers use), then it might be worth considering removing
> the 'identifier' completely and just have unique event names (this
> could assume that an Event Manager should be aware of all the events
> that it supports?). Another reason supporting this is, if the MVC
> Application Event Manager is shared by all, then the identifier param
> in its Shared Event Manager becomes redundant?

No. This means the event names have to be unique per component
triggering events. This gets very limiting very quickly, or requires a
ton of extra work to wire an event to listen to every possible object.
As an example, right now, you can attach a listener to the
SharedEventManager using the context
"Zend\Stdlib\DispatchableInterface", and any controller that registers
an EM instance with that context -- which any controller extending from
the abstract controllers we ship do currently -- will be able to trigger
an event that listener will be able to react to. If we had per-class
event names, the listeners either need to know every possible class in
the application they should listen to, or the objects triggering events
all have to use the same exact event names. This latter situation is
limiting, because then a listener cannot choose to listen to an event
triggered by one controller, but not another.

Long story short: The current situation answers a ton of different use
cases, and we're not going to change the design at this point.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Shared Event Manager

Gregory
On Sat, Jun 30, 2012 at 6:13 PM, Matthew Weier O'Phinney
<[hidden email]> wrote:
> Please look at Zend\Mvc\Service\EventManagerFactory for details on how
> the shared version of the SharedEventManager is implemented,

I overlooked that the Service\EventManagerFactory can be resused,
however that still leaves the 'identifiers' to be initialized by other
means? That's not so obvious from the factory alone.

>    function ($sm) {
>        $component = new Some\Component();
>        $component->setEventManager($sm->get('EventManager');
>        return $component;
>    }
>
> This ensures all is wired correcly, and the SharedEventManager is
> correctly injected.

But in the above the 'EventManager' is now assigned new identifiers?
And/or new identifiers may have to be added?



> We chose not to use aliases, as
> aliases are much, much harder to document, and require documentation to
> understand what they refer to (class names and interface names are
> self-explanatory and thus self-documenting).

My concern there is that if the EventManager (or component) changes
via the Service Locator then the identifiers may automatically change
if they are dynamically determined by the current class name?


> No. This means the event names have to be unique per component
> triggering events.

Isn't that required now, I thought that for any given EM the event
names have to be unique?

> As an example, right now, you can attach a listener to the
> SharedEventManager using the context
> "Zend\Stdlib\DispatchableInterface",
<snip>
> This latter situation is
> limiting, because then a listener cannot choose to listen to an event
> triggered by one controller, but not another.

I'll have to look into that to understand more.


> Long story short: The current situation answers a ton of different use
> cases, and we're not going to change the design at this point.

I'm merely seeking how it might be possible to make it simpler to use
without requiring too much knowledge of the underlying code and not to
remove what it can do, e.g Shared can mean different things depending
on how that component is initialized.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Shared Event Manager

weierophinney
Administrator
-- Greg <[hidden email]> wrote
(on Saturday, 30 June 2012, 09:48 PM -0500):
> On Sat, Jun 30, 2012 at 6:13 PM, Matthew Weier O'Phinney
> <[hidden email]> wrote:
> > Please look at Zend\Mvc\Service\EventManagerFactory for details on how
> > the shared version of the SharedEventManager is implemented,
>
> I overlooked that the Service\EventManagerFactory can be resused,
> however that still leaves the 'identifiers' to be initialized by other
> means? That's not so obvious from the factory alone.

It's up to each class receiving an EM instance to assign identifiers. If
you look in the various EM-aware classes in the framework, they do so
inside setEventManager(). This is the appropriate place to do so. The
class should tell the EM what contexts it is interested in.

> >    function ($sm) {
> >        $component = new Some\Component();
> >        $component->setEventManager($sm->get('EventManager');
> >        return $component;
> >    }
> >
> > This ensures all is wired correcly, and the SharedEventManager is
> > correctly injected.
>
> But in the above the 'EventManager' is now assigned new identifiers?
> And/or new identifiers may have to be added?

See above.

> > We chose not to use aliases, as aliases are much, much harder to
> > document, and require documentation to understand what they refer to
> > (class names and interface names are self-explanatory and thus
> > self-documenting).
>
> My concern there is that if the EventManager (or component) changes
> via the Service Locator then the identifiers may automatically change
> if they are dynamically determined by the current class name?

No, see above.

> > No. This means the event names have to be unique per component
> > triggering events.
>
> Isn't that required now, I thought that for any given EM the event
> names have to be unique?

They are unique within the _class_, but not unique within the
_framework_. This ensures the granularity of attachment I described
previously in the thread.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Shared Event Manager

Gregory
In following the existing code, to me it seems a little easier if there is

class SharedEventManagerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new SharedEventManager();
    }
}

Which the EventManagerFactory would use

class EventManagerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $em = new EventManager();
        $em->setSharedManager($serviceLocator->get('SharedEventManager'));
        return $em;
    }
}


This would mean that we would remove the need of having to access (or
find) and em in order to add a shared listener.

E.g in a module bootstrap:

public function onBootstrap($event)
{
    $em = $event->getApplication()->getServiceManager()->get('SharedEventManager');

    $em->attach('member', 'addMember', function() {
        var_dump(__LINE__.' '.__FILE__);
    });
}

At this point, I would be considering whether it would be worthwhile
adding a 'getSharedEventManager' method to the Application class. The
somewhat point here is that for some, we're skipping the whole
eduction of the EventManager, and making it easy to add a listener to
be added.

However at this point, for me at least, is where things start to
revert back to becoming complicated. A question in my mind here, is
why wouldn't the shared event manager then be able to trigger events -
this implies the user really doesn't care how the listeners are
contained, e.g. $em->trigger('member', 'addMember');

In summarizing my thoughts, it should be easy as

//attach listener
$em->attach('member.addMember', function() {
        var_dump(__LINE__.' '.__FILE__);
});

//trigger listeners
$em->trigger('member.addMember');


or if you want to listen to an event from a specific object, something
of the following nature


$em->attach(
  'member.addMember',
  function() {
        var_dump(__LINE__.' '.__FILE__);
  },
  'Application\Controller\IndexController'
);

$em->trigger('member.addMember', $this);


Thanks.





















On Sun, Jul 1, 2012 at 11:10 AM, Matthew Weier O'Phinney
<[hidden email]> wrote:

> -- Greg <[hidden email]> wrote
> (on Saturday, 30 June 2012, 09:48 PM -0500):
>> On Sat, Jun 30, 2012 at 6:13 PM, Matthew Weier O'Phinney
>> <[hidden email]> wrote:
>> > Please look at Zend\Mvc\Service\EventManagerFactory for details on how
>> > the shared version of the SharedEventManager is implemented,
>>
>> I overlooked that the Service\EventManagerFactory can be resused,
>> however that still leaves the 'identifiers' to be initialized by other
>> means? That's not so obvious from the factory alone.
>
> It's up to each class receiving an EM instance to assign identifiers. If
> you look in the various EM-aware classes in the framework, they do so
> inside setEventManager(). This is the appropriate place to do so. The
> class should tell the EM what contexts it is interested in.
>
>> >    function ($sm) {
>> >        $component = new Some\Component();
>> >        $component->setEventManager($sm->get('EventManager');
>> >        return $component;
>> >    }
>> >
>> > This ensures all is wired correcly, and the SharedEventManager is
>> > correctly injected.
>>
>> But in the above the 'EventManager' is now assigned new identifiers?
>> And/or new identifiers may have to be added?
>
> See above.
>
>> > We chose not to use aliases, as aliases are much, much harder to
>> > document, and require documentation to understand what they refer to
>> > (class names and interface names are self-explanatory and thus
>> > self-documenting).
>>
>> My concern there is that if the EventManager (or component) changes
>> via the Service Locator then the identifiers may automatically change
>> if they are dynamically determined by the current class name?
>
> No, see above.
>
>> > No. This means the event names have to be unique per component
>> > triggering events.
>>
>> Isn't that required now, I thought that for any given EM the event
>> names have to be unique?
>
> They are unique within the _class_, but not unique within the
> _framework_. This ensures the granularity of attachment I described
> previously in the thread.
>
> --
> Matthew Weier O'Phinney
> Project Lead            | [hidden email]
> Zend Framework          | http://framework.zend.com/
> PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc



--
Greg
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Shared Event Manager

weierophinney
Administrator
-- Greg <[hidden email]> wrote
(on Sunday, 01 July 2012, 12:52 PM -0500):

> In following the existing code, to me it seems a little easier if
> there is
>
> class SharedEventManagerFactory implements FactoryInterface
> {
>     public function createService(ServiceLocatorInterface $serviceLocator)
>     {
>         return new SharedEventManager();
>     }
> }
>
> Which the EventManagerFactory would use
>
> class EventManagerFactory implements FactoryInterface
> {
>     public function createService(ServiceLocatorInterface $serviceLocator)
>     {
>         $em = new EventManager();
>         $em->setSharedManager($serviceLocator->get('SharedEventManager'));
>         return $em;
>     }
> }

I agree on this count, and actually already have it in my todo list;
I'll get a PR ready today.

> This would mean that we would remove the need of having to access (or
> find) and em in order to add a shared listener.
>
> E.g in a module bootstrap:
>
> public function onBootstrap($event)
> {
>     $em = $event->getApplication()->getServiceManager()->get('SharedEventManager');

Actually, to be honest, previously I would have written:

    $app    = $event->getTarget();
    $em     = $app->getEventManager();
    $shared = $em->getSharedManager();

Still three levels of chaining, though.

The above notation _feels_ semantically more correct to me, as it's the
same pattern I'd use elsewhere when I don't have access to the service
manager -- I'd pull the shared event manager out of the composed event
manager.

Either way works, though.

>     $em->attach('member', 'addMember', function() {
>         var_dump(__LINE__.' '.__FILE__);
>     });
> }
>
> At this point, I would be considering whether it would be worthwhile
> adding a 'getSharedEventManager' method to the Application class. The
> somewhat point here is that for some, we're skipping the whole
> eduction of the EventManager, and making it easy to add a listener to
> be added.

This seems reasonable, but I worry a little about having too many
accessors on the Application instance. That said, the Application
instance's primary responsibilities are marshalling services and wiring
events, so having an accessor for the shared manager makes a degree of
sense.

> However at this point, for me at least, is where things start to
> revert back to becoming complicated. A question in my mind here, is
> why wouldn't the shared event manager then be able to trigger events -
> this implies the user really doesn't care how the listeners are
> contained, e.g. $em->trigger('member', 'addMember');

The shared manager is not supposed to trigger events. It's supposed to
simply aggregate listeners. The point is to provide a well-known object
you can register against when you do not have access to the object that
will be triggering the event.

So, as an example: we want to register a listener against the
"dispatch" event of _controllers_ (not the Application) in order to
determine which layout to use. This listener will examine the target (a
controller) for existence of a particular property, and then modify the
template of the event's view model accordingly:

    $shared->attach('Zend\Stdlib\Dispatchable', 'dispatch', function ($e) {
        $controller = $e->getTarget();
        if (!isset($controller->layout)) {
            // no layout property, not interested
            return;
        }

        $layoutModel = $e->getViewModel();
        $layoutModel->setTemplate($controller->layout);
    });

We don't particularly care which controller we attach to, and we
certainly won't have an instance. However, we _do_ care that the target
_is_ a controller -- which is why we specify the context (the first
argument). Only objects that set an identifier of
'Zend\Stdlib\Dispatchable' on their composed EM instance will trigger
this.

Now, notice I said the "dispatch" event of controllers, and not the
Application. They _both_ trigger a dispatch event -- one is triggered
within the other.

If we had a single EM instance that we pushed everywhere, this becomes
more difficult -- they'd have to have distinct names. And it would mean
restricting functionality: If we have a common event name on
controllers, how can we attach to a single controller or subset of
controllers, without requiring an instance (or instances) of the
controller(s)?

Let's continue with the subject of event naming. Right now, context
identifiers and event names are predictable. Our convention with context
identifiers is class names and interface names, while the convention
with event names is the name of the method triggering the event. If we
have a single, shared event manager instance everywhere, how do we name
the events? The examples you use are using arbitrary strings -- these
then need to be documented somewhere, so that developers can look up and
see who triggers what. If we went a conventions-based approach, we run
into the issue that one class might trigger one name, and another
derivative class another -- which means listeners now have to attach to
both individually -- more boilerplate.

I appreciate the suggestions you're making -- but I actually think
they'd sacrifice a lot of functionality and create more complexity in
the end.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Shared Event Manager

Gregory
On Sun, Jul 1, 2012 at 3:43 PM, Matthew Weier O'Phinney
<[hidden email]> wrote:
> If we had a single EM instance that we pushed everywhere, this becomes
> more difficult -- they'd have to have distinct names.

No more different than the concatenation of $identifier.'.'.$event_name.

It is also not much more different than the steps that an EventManager
would have to take in order to ensure its identifiers are distinct.

> And it would mean
> restricting functionality: If we have a common event name on
> controllers, how can we attach to a single controller or subset of
> controllers, without requiring an instance (or instances) of the
> controller(s)?


The example demonstrates the problem if the identifiers were the same
and not distinct. Even so, the following still work:

$em->attach(
  'member.addMember',
  function() {
        var_dump(__LINE__.' '.__FILE__);
  },
  'Application\Controller\IndexController'
);


The listener is additionally specifying which sources it is only interested in.

>
> Let's continue with the subject of event naming. Right now, context
> identifiers and event names are predictable.


Which can also be determined from $this.


> Our convention with context
> identifiers is class names and interface names, while the convention
> with event names is the name of the method triggering the event. If we
> have a single, shared event manager instance everywhere, how do we name
> the events? The examples you use are using arbitrary strings -- these
> then need to be documented somewhere, so that developers can look up and
> see who triggers what.

Ideally not completely arbitrary, e.g without vendor name, documented,
and emitted by $this.

On the other hand, the Event Managers are/can also create arbitrary
identifiers which probably would have to be documented. $this gives
all this information.

> If we went a conventions-based approach, we run
> into the issue that one class might trigger one name, and another
> derivative class another -- which means listeners now have to attach to
> both individually -- more boilerplate.

Not if you explicitly specify $this? At least to some degree.

The more distinctly definitive the event name, the closer it is to
targeting listeners without requiring specific knowledge of the source
from which the event is being emitted?

E.g

mvc.bootstrap
mvc.controller.bootstrap


> I appreciate the suggestions you're making -- but I actually think
> they'd sacrifice a lot of functionality and create more complexity in
> the end.

In my example, $this provides the same information that would be
provided to EventManagers as identifiers.

However some consequences come to mind:

- Identifiers are computationally determined from the source object
(i.e. not configured or hard coded).
- Should it be possible for one component to access another components
event manager and trigger listeners - at which point we still would
not know the originating object.

For example

$event  = new MvcEvent();

$event->setName('mvc.bootstrap')
      ->setTarget($this)
      ->setApplication($this)
      ->setRequest($this->getRequest())
      ->setResponse($this->getResponse())
      ->setRouter($serviceManager->get('Router'));


$em->trigger($event);

Here the target is the source object emitting the event, and the
Shared Event Manager could iterate through all the listeners for that
event name. If the registered listeners provide additional information
about which objects (class and interface names) that it additionally
wants to target, then the event manager would only call that listener
if there is a match.

Another example might be:

$em->attach(
  'mvc.controller.bootstrap',
  function() {}, //callback
  function($source) {} //match event source
 });

And to attach a listener to all events from a particular object:

$em->attach(null, function() {}, function($source) { .... match $source .... });

To summarize a SharedEventManager could trigger listeners as long as
$this is passed. $this would replace the necessity of each component
having an event manager and the identifiers would be determined from
the class and interface names of $this.

Allowing the Shared Manager to trigger events in this way would just
be an alternative to the existing methodology.

I appreciate you walking me through this, I now better understand the
derivation of the EventManager.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Shared Event Manager

weierophinney
Administrator
Greg --

I see what some of your points are. However, at this time, we're
circling in on beta5, and planning RC status following that. The design
we have right now is well-tested, and covers the variety of use cases
required by the framework; further, I've not seen many issues raised
against it -- either technically or usability-wise -- particularly in
recent months. As such, I'm unlikely to make changes at this point.

If you're dissatisfied with the current design, I suggest you start
working up an alternate implementation, testing it in applications, and
then proposing it for the 3.0 release. Based on community feedback, we
plan to do major releases every 18-24 months so as to minimize the
amount of refactoring, and thus backwards incompatible breakage, done
in any given major release. As such, if the solution you develop offers
clear advantages over what we ship in 2.0, you won't have to wait a
tremondously long time before seeing it in a released version.

Thanks for taking the time to analyze the component in depth!

-- Greg <[hidden email]> wrote
(on Sunday, 01 July 2012, 10:32 PM -0500):

> On Sun, Jul 1, 2012 at 3:43 PM, Matthew Weier O'Phinney
> <[hidden email]> wrote:
> > If we had a single EM instance that we pushed everywhere, this becomes
> > more difficult -- they'd have to have distinct names.
>
> No more different than the concatenation of $identifier.'.'.$event_name.
>
> It is also not much more different than the steps that an EventManager
> would have to take in order to ensure its identifiers are distinct.
>
> > And it would mean
> > restricting functionality: If we have a common event name on
> > controllers, how can we attach to a single controller or subset of
> > controllers, without requiring an instance (or instances) of the
> > controller(s)?
>
>
> The example demonstrates the problem if the identifiers were the same
> and not distinct. Even so, the following still work:
>
> $em->attach(
>   'member.addMember',
>   function() {
>         var_dump(__LINE__.' '.__FILE__);
>   },
>   'Application\Controller\IndexController'
> );
>
>
> The listener is additionally specifying which sources it is only interested in.
>
> >
> > Let's continue with the subject of event naming. Right now, context
> > identifiers and event names are predictable.
>
>
> Which can also be determined from $this.
>
>
> > Our convention with context
> > identifiers is class names and interface names, while the convention
> > with event names is the name of the method triggering the event. If we
> > have a single, shared event manager instance everywhere, how do we name
> > the events? The examples you use are using arbitrary strings -- these
> > then need to be documented somewhere, so that developers can look up and
> > see who triggers what.
>
> Ideally not completely arbitrary, e.g without vendor name, documented,
> and emitted by $this.
>
> On the other hand, the Event Managers are/can also create arbitrary
> identifiers which probably would have to be documented. $this gives
> all this information.
>
> > If we went a conventions-based approach, we run
> > into the issue that one class might trigger one name, and another
> > derivative class another -- which means listeners now have to attach to
> > both individually -- more boilerplate.
>
> Not if you explicitly specify $this? At least to some degree.
>
> The more distinctly definitive the event name, the closer it is to
> targeting listeners without requiring specific knowledge of the source
> from which the event is being emitted?
>
> E.g
>
> mvc.bootstrap
> mvc.controller.bootstrap
>
>
> > I appreciate the suggestions you're making -- but I actually think
> > they'd sacrifice a lot of functionality and create more complexity in
> > the end.
>
> In my example, $this provides the same information that would be
> provided to EventManagers as identifiers.
>
> However some consequences come to mind:
>
> - Identifiers are computationally determined from the source object
> (i.e. not configured or hard coded).
> - Should it be possible for one component to access another components
> event manager and trigger listeners - at which point we still would
> not know the originating object.
>
> For example
>
> $event  = new MvcEvent();
>
> $event->setName('mvc.bootstrap')
>       ->setTarget($this)
>       ->setApplication($this)
>       ->setRequest($this->getRequest())
>       ->setResponse($this->getResponse())
>       ->setRouter($serviceManager->get('Router'));
>
>
> $em->trigger($event);
>
> Here the target is the source object emitting the event, and the
> Shared Event Manager could iterate through all the listeners for that
> event name. If the registered listeners provide additional information
> about which objects (class and interface names) that it additionally
> wants to target, then the event manager would only call that listener
> if there is a match.
>
> Another example might be:
>
> $em->attach(
>   'mvc.controller.bootstrap',
>   function() {}, //callback
>   function($source) {} //match event source
>  });
>
> And to attach a listener to all events from a particular object:
>
> $em->attach(null, function() {}, function($source) { .... match $source .... });
>
> To summarize a SharedEventManager could trigger listeners as long as
> $this is passed. $this would replace the necessity of each component
> having an event manager and the identifiers would be determined from
> the class and interface names of $this.
>
> Allowing the Shared Manager to trigger events in this way would just
> be an alternative to the existing methodology.
>
> I appreciate you walking me through this, I now better understand the
> derivation of the EventManager.
>

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Loading...