Loosely coupled events in .NET (and harvesting Open Source projects)
/ 6 min read
This post is about how Open Source projects can be very beneficial in creating the best solution for your own development challenges.
A little while ago, I needed something to handle events in a loosely coupled manner due to a plugin-like architecture. Since I’m not the first person on earth who needs this, I went out looking for what’s available in .NET land and ended up with the EventAggregator from Caliburn Micro:
1. Caliburn Micro (EventAggregator)
The nicest thing is that it allows subscribers to handle multiple events by just implementing an interface:
Note that you can use ANY object as message. I like that!
Unfortunately, the application I’m working on is an ASP.NET MVC web application where the EventAggregator is more suitable for stateful environments like Silverlight or WPF. For example, I had to make the EventAggregator a Singleton to make sure that subscribers with different lifestyles (per web request, singleton, ASP.NET provider) could be called properly. Another issue was that I couldn’t find a nice way to instantiate all subscribers in the application.
2. FunnelWeb (EventPublisher)
While browsing the Funnelweb source code, I stumbled upon an interesting EventPublisher class, the EventAggregator of Funnelweb. This class takes a constructor dependency on a list of objects that implement IEventListener. So no subscribing here. The advantage of this is that an IoC container can take care of all subscriber creation and you don’t have to worry anymore if all subscribers are instantiated and are subscribed. When an event is published, the EventPublisher just goes through the list of IEventListener subscribers and calls their Handle() method. A small drawback is that the subscribers have to find out if they can handle the published event themselves. All events are published to all subscribers whatever type of event.
3. Mix and Match and add a little sauce
I really like the approach that is taken in Funnelweb so I’ve taken that as the base for my solution and added the parameterized event listeners of Caliburn Micro.
The event listener interface:
An event listener implementation:
The event publisher interface:
The event publisher implementation:
By creating a generic Publish
4. Use it!
To be honest, you pretty much need an IoC container to use the full power of this EventPublisher, and to be more specific: an IoC container that can inject the IEnumerable
Let’s say we have an application service IMyService and a plugin IPlugin, implemented by MyService and MyPlugin. MyService publishes an event with the type of MyEvent and MyPlugin handles that event. IMyService is being used in an ASP.NET MVC controller.
Event, Service and Plugin:
Wire things together in the IoC container (Autofac):
Note that the plugins (our IEventListener) can have a different lifestyle (Singleton) than the IEventPublisher (Instance per HTTP request). This should be fine as long as the IEventListeners live longer or have the same lifestyle as the IEventPublisher.
Finally the ASP.NET MVC controller:
That’s it! Thank you both Caliburn Micro and Funnelweb! I’m pretty happy with this solution and use it for multiple scenario’s:
-
Plugins that need to respond on events of the core system;
-
Separation of concerns in Application Services: I often have an Application Service that needs to do a little more than it was originally designed for, for example post-processing of an order. Now I only need to publish an event with the order as data and the appropriate application services pick it up and perform the post-processing;
-
Dirty things with custom ASP.NET providers. Just implement one or more IEventListener
interfaces and register the provider instance in the IoC container with the interfaces it implements.
Just one thing that worries me a little is the dependency of the EventPublisher to all classes that implement IEventListener