views:

272

answers:

2

At work the product i get to maintain has a lot of "moving parts" one of the main sticking points I have with how its architected is that should ten different locations need to know that a new item in a list is selected, a direct code path must be coded. For example in the following layout.

                          Form1
                            |
        +-------------------+---------------------+
        |                   |                     |
     Control1            Control2              Control3
        |                   |                     |
        |             +-----------+          +----+----+
        |             |           |          |         |
SelectionList       View1       View2      View3     View4

(The real application I work on has more layers than this for the GUI components... bleh...)

If we add another view to any control, which depends on which item is selected, Form1 needs to route the message. Worse yet, if we add various commands which could be invoked on a selected item, from the selection list or any of the views, the views need to be modified, to properly invoke the action. Usually such actions are housed in Form1 (and available via a main menu option too...)

(Think of the SelectionList like a list of files...)

This seems fragile and cumbersome.

Lately I've been toying with the idea of making (or acquiring if the price is right) a subsystem within an app that the publishers of events (such as commands) and subscribers only need to know of the definition of the event arguments and the name of the event in order to receive the event.

My questions are:

  1. Is there a commercial, open-source, or public domain library that already does this in .Net 3.5? (I use C#.) This needs to be an INTRA-APPLICATION mechanism. I already know of interapplication libraries and mechanisms like MSMQ and This Codeplex project.

  2. If you have experience developing or using solutions like these, what are the top 3 pitfalls to avoid?

+1  A: 

I would take a look at Prism (http://www.codeplex.com/compositewpf) which includes the EventAggregator service which does pretty much exactly what you want. The EventAggregator is not at all limited to WPF but the composite UI stuff is.

Josh Einstein
@ Josh. Thanks I'll check it out. I've already got an idea of how I want it to function. Hopefully this will do the trick and save me some time. As for the second question, do you have any experience using the EventAggregator? If so, what sorts of things would you advise avoid doing with it, despite being possible?
Jason D
Well, EventAggregator is pretty basic in nature so I can't really think of anything you wouldn't want to do with it because it pretty much does just one thing (pub/sub event management). I guess I would just suggest that you don't try to use it for everything. For example, use the command pattern and standard events where appropriate.
Josh Einstein
Thanks for the feedback. Work has been busy so no chance to try it yet. I'll probably try it out next week.
Jason D
+1  A: 

Could this serve as a ligthweight message passing framework?

function MyConstructor() {
    this.MessageQueues = {};

    this.PostMessage = function (Subject) {
        var Queue = this.MessageQueues[Subject];
        if (Queue) return function() {
                                        var i = Queue.length - 1;
                                        do Queue[i]();
                                        while (i--);
                                    }
        }

    this.Listen = function (Subject, Listener) {
        var Queue = this.MessageQueues[Subject] || [];
        (this.MessageQueues[Subject] = Queue).push(Listener);
    }
}

then you could do:

var myInstance = new MyConstructor();
myInstance.Listen("some message", callback());
myInstance.Listen("some other message", anotherCallback());
myInstance.Listen("some message", yesAnotherCallback());

and later:

myInstance.PostMessage("some message");

would dispatch the queues

Juaco
I do not want the receiver to know about the instance of the sender. In the code you provided this is still the case. As well at the time I accepted the answer the Microsoft page had detailed information on their even brokering subsystem in WPF. I used that as inspirational material for my own winforms implementation. (I didn't want to introduce a dependency on WPF into an app with numerous heterogeneous technologies - ActiveX, COM, C++, WTL, ATL, Winforms.)
Jason D
I fail to see where the receiver knows anything about the sender, it's more the opposite: the sender is the one that posts a message to a receiver that only has "to exist". The receiver only "pays attention" to some arbitrary messages in the form of arbitrary callbacks pushed on those messages queues...this can be further decoupled by placing all the message queues in a central "postoffice", a well known technique also.
Juaco