I have a static generic class that helps me move events around with very little overhead:
public static class MessageBus<T> where T : EventArgs
{
public static event EventHandler<T> MessageReceived;
public static void SendMessage(object sender, T message)
{
if (MessageReceived != null)
MessageReceived(sender, message);
}
}
To create a system-wide message bus, I simply need to define an EventArgs class to pass around any arbitrary bits of information:
class MyEventArgs : EventArgs
{
public string Message { get; set; }
}
Anywhere I'm interested in this event, I just wire up a handler:
MessageBus<MyEventArgs>.MessageReceived += (s,e) => DoSomething();
Likewise, triggering the event is just as easy:
MessageBus<MyEventArgs>.SendMessage(this, new MyEventArgs() {Message="hi mom"});
Using MessageBus and a custom EventArgs class lets me have an application wide message sink for a specific type of message. This comes in handy when you have several forms that, for example, display customer information and maybe a couple forms that update that information. None of the forms know about each other and none of them need to be wired to a static "super class".
I have a couple questions:
fxCop complains about using static methods with generics, but this is exactly what I'm after here. I want there to be exactly one MessageBus for each type of message handled. Using a static with a generic saves me from writing all the code that would maintain the list of MessageBus objects.
Are the listening objects being kept "alive" via the MessageReceived event?
For instance, perhaps I have this code in a Form.Load event:
MessageBus<CustomerChangedEventArgs>.MessageReceived += (s,e) => DoReload();
When the Form is Closed, is the Form being retained in memory because MessageReceived has a reference to its DoReload method? Should I be removing the reference when the form closes:
MessageBus<CustomerChangedEventArgs>.MessageReceived -= (s,e) => DoReload();