Monday, December 8, 2008

Dish #1: Generic Singleton base class

#region Copyright
///Copyright 2008 Codesagar.
///DISCLAIMER: Author claims no responsibility for any damages whatsoever
///stemming out either directly or indirectly from the usage of any of the
///source code made available through Codesagar.
#endregion

using System;

///Codesagar factory dishes
namespace Factories
{
    ///
    /// This class provides a generic singleton base class that provides a static member
    /// of the derived type tha points to the singleton instance. Ths class also provides
    /// the public singleton getter Instance to access the public interface of the derived 
    /// class.
    ///
    /// The derived class that should be used as a singleton
    public class SingletonBase where T : class, new()
    {
        #region protected static instance
        protected static T s_instance;
        #endregion

        #region protected constructor
        protected SingletonBase()
        {
        }
        #endregion

        #region Singleton interface
        public static T Instance
        {
            get
            {
                if (s_instance == null)
                {
                    T instance = new T();
                    // Insure all writes used to construct new value have been flushed.
                    // For more, see 
                    // http://blogs.msdn.com/brada/archive/2004/05/12/volatile-and-memorybarrier.aspx
                    System.Threading.Thread.MemoryBarrier();
                    s_instance = instance;
                }

                return s_instance;
            }
        }
        #endregion
    }

    ///
    /// A sample singleton class that derives its singleton properties
    /// from the Singleton
    ///
    class MySingleton : SingletonBase
    {
        public void Test()
        {
            Console.WriteLine("MySingleton::Test called!");
        }
    }

    public class Client
    {
        public void TestMySingleton()
        {
            MySingleton.Instance.Test();
        }
    }
}

No comments: