The Journey of the Lunch Launcher: Part 6 - Processing messages

Part 1 - The origins of the 'lunch launcher'
Part 2 - MEDC 2007
Part 3 - Managing the Transport
Part 4 - Sending messages
Part 4b - The output channel
Part 5 - Receiving messages

Last time, I talked about how the Lunch Launcher receives messages.  Today's topic is now the messages are processed.

As with all entries in this series, please note that the following disclaimer covers all examples contained herein.
//-----------------------------------------------------------------------//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A//PARTICULAR PURPOSE.//-----------------------------------------------------------------------
MEDC 2007
Just like the listeners, the MEDC 2007 version of the Lunch Launcher demo contained three nearly identical processing methods.
/// <summary>/// Processes a received lunch invitation/// </summary>/// <param name="msg">/// The lunch invitation message/// </param>/// <param name="from">/// The email address of the sender/// </param>private void ProcessInvitation(Message msg, String from){    LunchObjectSerializer serializer =         new LunchObjectSerializer(typeof(LunchInvitation));

    // get the buddy who sent the invitation
    Buddy buddy = LookupBuddy(from);
           
    // ignore invitations from those who
    //  are not in the buddy list
    if(null != buddy)
    {
        // get the invitation
        LunchInvitation invitation =
            msg.GetBody<LunchInvitation>(serializer);
           
        // notified registered event handlers
        SendInvitationReceived(
            new InvitationReceivedEventArgs(buddy, invitation));
    }
}

When a message is processed, the method creates a serializer for the LunchInvitation object to be used when the message body is extracted.

Next, the sender of the invitation is compared with the user's buddy list.  This is done to avoid unsolicited invitations from people with whom the user would rather not have lunch.

If the sender is found in the buddy list, the message body is retrieved and the user interface is notified.  When the user interface handles the event, it presents the user with a 'you have been invited' form.

Current version
In the current version (October 2007), the processing methods have been consolidated into a single generic method.
/// <summary>/// Process a received message/// </summary>/// <typeparam name="T">/// The type of object contained within the message/// </typeparam>/// <param name="msg">/// The lunch invitation message/// </param>/// <param name="from">/// The email address of the sender/// </param>private void ProcessMessage<T>(Message msg, String from){    // get the buddy who sent the message    Buddy buddy = LookupBuddy(from);                // ignore invitations from those who    //  are not in the buddy list    if(null != buddy)    {        // get the serializer        LunchObjectSerializer serializer = GetSerializer<T>();

        // get the invitation
        T payload = msg.GetBody<T>(serializer);
           
        // notified registered event handlers
        SendMessageReceived(
            new LunchLauncherMessageReceivedEventArgs<T>(buddy, payload));
    }
}

There are a few changes to this version.  First, like last time's example, the serializer is retrieved from a class-global collection.  This saves on reflection costs and reduces the amount garbage generated as the application receives messages.

The second change is the consolidation of the event handlers into a generic method.  As I was reviewing the code right after my session, I took notes on the areas where code was highly similar.  Wherever possible, I merged the methods into generic versions.  This has resulted in much less code to review :) and fewer issues to investigate.  Fixing once is much better than fixing multiple times, or worse yet, forgetting to apply the fix to one of the duplicates.

Lastly, I moved the serializer retrieval into the conditional block.  There is no need to fetch it unless we recognize the sender of the message -- a very small performance increase.

In closing
We are getting towards the end of this series -- there are only a couple more topics that I would like to cover.  I hope you are enjoying reading about my experiences writing the Lunch Launcher demo.  As I mentioned last time, as I continue to work on the demo, I plan on keeping the examples in this series fresh.  This will likely result in edits (read: extensions) to the posts in this series.  As I make changes, I will post a topic pointing them out.

Next up, a look at the 'lunch manager'.

Take care,
-- DK

Disclaimer(s):
This posting is provided "AS IS" with no warranties, and confers no rights.
The information contained within this post is in relation to beta software. Any and all details are subject to change.