C# 3.0 Extension Methods As Adapters

[digg]

Extension methods provide public / internal extensions to the already existing types. And the design pattern that provides this functionality is the visitor pattern, but the draw back of the visitor is you have to have all the hooks planted in the class hierarchy  according to the pattern to make it workable. But the extension methods provide you this pattern right out of the box. I’ll go into more details of the visitor pattern some later time, I have plans to discuss the design patterns in details.

I’ll show you how we can use the extension methods to work like adapters. Adapter design pattern, also known as a wrapper pattern, is used to take care of incompatibilities between objects, more on it in some later session. If you ever developed a java application, the objects in java have inbuilt  capability of thread synchronization like waiting on an object to be signaled using the methods like notify, wait etc. I was thinking to get the same  functionality using C#. C# provides the functionality through System.Threading.Monitor class that allows synchronization between threads within the same process. Here is how we can achieve this java functionality in C#.

using System.Threading;

namespace System
{
    public static class ObjectExtension
    {
        public static void Enter(this object obj)
        {
            Monitor.Enter(obj);
        }

        public static void Exit(this object obj)
        {
            Monitor.Exit(obj);
        }

        public static void Notify(this object obj)
        {
            Monitor.Pulse(obj);
        }

        public static void NotifyAll(this object obj)
        {
            Monitor.PulseAll(obj);
        }

        public static bool Wait(this object obj)
        {
            return Monitor.Wait(obj);
        }

        public static bool Wait(this object obj, int millisecondsTimeout)
        {
            return Monitor.Wait(obj, millisecondsTimeout);
        }
    }
}

Here is an example class for its minimal usage –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Shams
{
    [Serializable]
    public class Example
    {
        private static Object SyncObject = new Object();

        // Constructors
        public Example() { }

        public bool Block()
        {
            lock (SyncObject)
            {
                bool status = true;

                try
                {
                    status = SyncObject.Wait();
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine(ex.ToString());
                    status = false;
                }
                return status;
            }
        }

        public void Release()
        {
            lock (SyncObject)
            {
                SyncObject.Notify();
            }
        }

        public void ReleaseAll()
        {
            lock (SyncObject)
            {
                SyncObject.NotifyAll();
            }
        }
    }
}

And here is our test app with entry point, Main…

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace Shams
{
    class Program
    {
        static void Main(string[] args)
        {
            // creat the example object
            Example example = new Example();
            Debug.WriteLine("Main thread..." + 
                Thread.CurrentThread.GetHashCode().ToString());
            new Thread(delegate()
            {
                //// block for ever...
                Debug.WriteLine("Entering thread..." + 
                    Thread.CurrentThread.GetHashCode().ToString());
                
                example.Block();
                
                Debug.WriteLine("Leaving thread..." + 
                    Thread.CurrentThread.GetHashCode().ToString());
            }).Start();

            // lets sleep for 5 secs, tired need rest..
            System.Threading.Thread.Sleep(5000);
            example.Release();
            
            System.Threading.Thread.Sleep(1000);
            Debug.WriteLine("Main thread again..." + 
                Thread.CurrentThread.GetHashCode().ToString());
            
            /*  The output is :-
             *  Main thread...9
             *  Entering thread...10
             *  Leaving thread...10
             *  The thread 0x16c4 has exited with code 0 (0x0).
             *  Main thread again...9
            */  
        }
    }
}

See how nicely we got the Adapter’s functionality using C# 3.0’s Extension mechanism that is we have extended the Objects functionality with the wrappers around the Monitors and that actually mimics the Adapters (The Adapter Design Pattern). I’ll give you more examples on it later, when i cover threading and LINQ topics. Looking forward to your comments and have a good one :)

If you enjoyed reading this blog, leave your valuable feedback and consider subscribing to the RSS feed. You can also subscribe to it by email. Also, you can follow me on Twitter. Thank you!

 

Technorati Tags: ,
Comments are closed