Introduction
This article introduces some techniques in developing applications that can route data / messages asynchronously to more than recipient. Following are the famous GOF patterns that are used in this article.
1. Observer Pattern
2. Singleton Pattern
Technique Defined
Client will not send the messages to the recipient. Instead they send the messages to a Controller class, who notifies the recipients upon receiving the messages. Controllers are message routers. Message is considered to be the target object that the recipients would be interested in. Recipients are called "observers" who awaits message signals from the controller. To receive the messages, the observers should register themselves with the controller. Entire architecture works in a "publish-subscribe" model.
Below diagram explains the architecture.

Building the Code
1. Abstract out the behaviors of all the observers.
public abstract class IObserver
{
public abstract void ProcessMessage(string strMessage);
}
2. Subclass the observer implementations. I have defined an audit class that logs all the incoming messages. This will be one of the observers that are registered to the router class.
public class MessageLogger : IObserver
{
private static StreamWriter sw = null;
private string strTempFilePath = string.Empty;
public MessageLogger()
{
string strTempFilePath = base.FilePath + "\\" + DateTime.Now.ToString("MMddyyyy");
if (!Directory.Exists(strTempFilePath.Trim()))
Directory.CreateDirectory(strTempFilePath.Trim());
FilePath = strTempFilePath + "\\MessageLog.txt";
}
public override void ProcessMessage(string strMessage)
{
lock (this)
{
sw = new StreamWriter(base.FilePath, true);
sw.WriteLine("[" + DateTime.Now.ToString("MM/dd/yyyy") + " " + DateTime.Now.ToLongTimeString() + "] " +
"Message : " + strMessage.Trim());
sw.Flush();
sw.Close();
}
}
}
3. Now let's construct the Router class.
It should expose a method for the observers to register themselves to get notified when the message arrives.
Router class should keep a holder (collection) to have all the observer's instances.
private static List<IObserver> lstObservers;
public void RegisterObserver(IObserver objObserverImpl)
{
if (!lstObservers.Contains(objObserverImpl))
{
lstObservers.Add(objObserverImpl);
}
}
Next method would be exposing a method (PrcoessMessage(string)) for the client to communicate the incoming messages for routing.
delegate void RouterDelegate(string strMessage);
public void PrcoessMessage(string strMessage)
{
RouterDelegate dlgtRouter = new RouterDelegate(this. NotifyMessage);
dlgtRouter.BeginInvoke(strMessage, null, null);
}
The above delegate refers to NotifyMessage() method which will be invoked asynchronously. NotifyMessage() method would then notifies the observers registered sequentially.
private void NotifyMessage(string strMessage)
{
foreach (IObserver observer in lstObservers)
{
observer.ProcessMessage(strMessage);
}
}
4. We should restrict the creation of multiple instances of the Router class because,

Mahesh ChandPosted Oct 1, 2009, 9:38 PM
Good article Chandramouli. You may want to upload the code with the article to make it easier for readers to understand. Keep up the good work! Cheers!