EventAggregator - Implementation Question

Topics: Framework Services, Getting Started
Aug 18, 2011 at 7:19 AM

I got a bit carried away with the EventAggregator as I was building my framework and was passing it down to base classes all over the place.  I had a few auto unsubscribe/subcribe scenarios and then I ran into an issue where I spawed a second instance of a view model and the first VM started responding to the requests I only expected the second instance to respond to.  Of course it makes sense I have a single EA that I was passing all over the place.

So then I started trying to subscribe/unsubscribe in the active/deactivate(saw that in the forums) and of course everything fell apart.

Now, while I have to re-think exactly how useful it is to publish data out to children, in stead of pushing through direct access to the objects, I do need some help on the basic best practice.

1) Do I just have one EA for the shell view that I pass around?  I assumed yes because I want to send message to the Shell from anywhere when I need to spawn a new window, but then I end up with this multiple instances responding when they don't need to.

2a) Should I be subscribing/unsubscribing as I tried doing in the activate/deactivate? 

or 2b)should I check in my IHandle method and ignore if it shouldn't fire when deactivated?

As I'm typing I'm thinking that 1 is a yes and 2b is a better approach.

What are people doing?  Should I be passing the EA down?  In some instances I'm using MEF and just pulling in the shellview's created instance.

Sorry for the babble... it's getting late.

Thanks Jack

Aug 18, 2011 at 11:47 AM

As always: it depends :-)

For communications to the Shell (which is typically singleton) I often prefer to define an interface IShell and let child VMs to interact directly with it.You can also define some specific UI services aimed to perform some specific UI task; IWindowManager is an example of this.

Personally, I avoid EA For communications from the Shell to its *direct* children, too.
To address this scenario I usually define an explicit interface for the children, thus letting the Shell to interact with them.

For more complex scenarios, expecially those involving communication with VMs at arbitrary depth, EA is a cleaner approach.
The instance of EA is typically singleton. 
To make sure that a message is only handled by the intended instance (for eaxmple: a reply to a previously sent request) I prefer using an Id (or CorrelationId).
Subscribe/Unsubscribe approach also worked well for me: what kind of issue have you had with it exaclty?

Aug 18, 2011 at 6:11 PM

Marco,

Thanks for the information.

So child VM’s can always pull down/reference IShell and make calls – that is a good idea even if I only have a couple of actionMessages at the moment.

The problem I’m having with EA from a parent VM to its children is that I have many child views that work with different pieces of the greater BO or user readonly parts of it and if any of them save or update bits and pieces I often want to refresh and push back certain pieces all while respecting the async nature of things. My development code is stuck in no man’s land a bit with respect to caching and proper sharing of data so I may need to revisit that.

Using the CorrelationId is a good idea / that definitely works for my multiple instances of same VM for different records. The problem I had with the subscribe/unsubscribe approach was that I had subscribe/unsubscribes all over the place, including base classes doing default actions. I had to debug to realize that my logic in the instatiated class wasn’t getting called because the base class had unsubscribed to the EA before re-subscribing again in its property setter. Just funny timing things.

So the plan is to rip it out and start over – and make sure I implement an opt-in vs. opt-out approach.

Thanks

jack

From: marcoamendola [email removed]
Sent: Thursday, August 18, 2011 4:48 AM
To: Jack Addington
Subject: Re: EventAggregator - Implementation Question [caliburnmicro:269512]

From: marcoamendola

As always: it depends :-)

For communications to the Shell (which is typically singleton) I often prefer to define an interface IShell and let child VMs to interact directly with it.You can also define some specific UI services aimed to perform some specific UI task; IWindowManager is an example of this.

Personally, I avoid EA For communications from the Shell to its *direct* children, too.
To address this scenario I usually define an explicit interface for the children, thus letting the Shell to interact with them.

For more complex scenarios, expecially those involving communication with VMs at arbitrary depth, EA is a cleaner approach.
The instance of EA is typically singleton.
To make sure that a message is only handled by the intended instance (for eaxmple: a reply to a previously sent request) I prefer using an Id (or CorrelationId).
Subscribe/Unsubscribe approach also worked well for me: what kind of issue have you had with it exaclty?

Aug 18, 2011 at 9:45 PM
Edited Aug 18, 2011 at 9:46 PM

Glad to be helpful.

Another option off the top of my head could be having a singleton instance of an observable model (implementing INPC).
Child View could simply bind read-only parts to this shared model; VMs responsible of updating part of the BO could just update the shared model upon successful edit completion. This way you have automatic update of the observing View and a comfortable central point of reference for the current BO state.

I like EA very much, but using MVVM I feel free to design the application model using the wider range of OO techniques available in code-only projects, without worrying too much of how the VM will be represented in the UI (bindings, converters and template are usually powerful enough).