Tuesday, June 26, 2012

Event Driven Architecture(EDA) – A simple notification system in .NET


Event-driven architecture (EDA) is a software architecture pattern promoting the production, detection, consumption of, and reaction to events. An event can be defined as "a significant change in state". (Wikipedia)
Event Driven system makes a loosely coupled enterprise system among components – because it is notification based.  An event-driven system typically consists of event emitters (or agents) and event consumers (or sinks). Sinks have the responsibility of applying a reaction as soon as an event is presented.
If we see publisher-Subscriber model, it has attractive properties. Subscribers are decoupled and each respectively unaware of the fact, which application will receive the message and who actually send the message. Similarly sender or publisher just triggers the messagees, and thats it.

"Consider an application sends one message that may be consumed by many disparate applications.  For example, when a customer calls into a call center to order broadband internet, the customer service rep enters order details into a CRM system.  When the order details have been captured, the CRM system submits the order for processing.  Various applications might be interested in that order, including the workflow system which manages the provisioning process and the Customer Data Store application which warehouses all customer records and the delivery application which actually ships the order. Though the publish/subscribe pattern, the CRM system simply publishes the "new order" message (only) knowing nothing about the applications that might be interested in it.  Interested systems then consume it and do work with the data". Read from here.

Decoupling in this way yields a powerful layer of extensibility whereby "n" number of applications can be integrated to consume messages with no modification required to those that produce them.

What is the message? To me I say it is a channel, a topic, an object information or whatever that is known to publishers and subscribers. Each message may also have more than one publisher, and publishers can be plugged or unplugged dynamically.
Messaging layer has responsibility to define messages/topics and know which subscribers are interested in which topics. I read about a nice idea of keeping topics as simple as just a string. It could be hierarchical and can support wild card message publishing (could be a requirement).  Moreover messages can have expiry time to be handle within the bracket.
My first step is to create a simple decoupled publish-subscriber framework where subscribers are decouples and are loaded through xml once dynamically.  This is a blocking and sequential enumeration of subscribers interested in a topic (implemented IConsumer<T>), and calling them in a single for loop to entertain each receiver. With such simple Notification system may be we can extend the idea in future to have asynchronous messaging, or even the receivers can be services (service bus?) I yet to explore it.

This article was good as starting point: I changed it according to my need.

I have following set of classes:


Here is a registration.xml to dynamically load the subscribers.
<?xml version="1.0" encoding="utf-8" ?>

<Events>
    <Subscribers>

      <Subscriber ClassName="EventHandler.Subscriber.Subscriber.OrderSubmittedConsumer.EmailNotificationConsumer" DllPath="..\..\..\EventHandler.Subscriber\bin\Debug\EventHandler.Subscriber.dll" />
      <Subscriber ClassName="EventHandler.Subscriber.Subscriber.OrderSubmittedConsumer.NotifyBOPConsumer" DllPath="..\..\..\EventHandler.Subscriber\bin\Debug\EventHandler.Subscriber.dll" />
      <Subscriber ClassName="EventHandler.Subscriber.Subscriber.OrderSubmittedConsumer.NotifyToInventoryConsumer" DllPath="..\..\..\EventHandler.Subscriber\bin\Debug\EventHandler.Subscriber.dll" />
      <Subscriber ClassName="EventHandler.Subscriber.Subscriber.OrderSubmittedConsumer.SaveEventInDBConsumer" DllPath="..\..\..\EventHandler.Subscriber\bin\Debug\EventHandler.Subscriber.dll" />
      <Subscriber ClassName="EventHandler.Subscriber.Subscriber.BookPublishedConsumer.PublishAnnouncementConsumer" DllPath="..\..\..\EventHandler.Subscriber\bin\Debug\EventHandler.Subscriber.dll" />
     
      <Subscriber ClassName="ExternalPlugin.RoyalBookFreeSampleConsumer" DllPath="..\..\..\ExternalPlugin\bin\Debug\ExternalPlugin.dll"/>
  
    </Subscribers>
</Events>

  •          IMessage: a message or a topic or a channel, what ever you say - information travel from publisher to subscribers.
  •         IEventPublisher: have single method to publish an event.
  •          ISubscriptionService: get the list of all interested subscriber based on their concrete IConcumer<> implementation

 public class PublishAnnouncementConsumer : IConsumer<BookPublishedMessage>

It tells framework that I am consumer of BookPublishedMessage, that is when ever it is published call my handle method and pass the message/topic information.

If want to play with this Notification System source code - I have one on sky drive. DOWNLOAD from skydrive. (FileName: EventDrivenModel.zip)

Overall Extended Idea:



Your comments are much appreciated.