Monday, December 6, 2010

The singleton pattern in C#

In software engineering, the singleton pattern is a design pattern used to ensure that an object has only one instance and provide a centralize point of access to itself. This pattern is needed when exactly one object is needed to coordinate actions across a system.

Example 1 – Generic singleton object:
A basic singleton object using lazy initialization (the object is not created until it is needed)
  public class MySingleton
    {
        private static MySingleton _instance;

        private MySingleton()
 {
 }

        /// <summary>
        /// Create an instance
        /// </summary>
        /// <returns>MySingleton</returns>
        public static MySingleton Create()
        {
            if (_instance == null)
            {
                _instance = new MySingleton();
            }
            return _instance;
        }
    }

Usage:
MySingleton o = MySingleton.Create();

Example 2 – Static singleton object:
A static singleton object does rely on the .NET CLR to initialize itself. A static singleton class needs to be sealed to ensure it won’t be derived.  This implementation also satisfies the design pattern; however, we lose some control over how our instance is initialized.
public sealed class MyStaticSingleton
{
        private static readonly MyStaticSingleton instance = new MyStaticSingleton();

        private MyStaticSingleton()
        {
       
        }

        public void SomeMethod()
        {

        }

        public static MyStaticSingleton Instance
        {
            get
            {
                return instance;
            }
        }
}

Usage:
MyStaticSingleton.Instance.SomeMethod();

Example 3 – Thread safe singleton object:
If our singleton object will resided in a multithreaded environment we will need to find a way to ensure that only one instance of our object will be created (in the presence of multiple threads).
The recommended solution for this problem is to use a Double-Check locking (http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html) .  By using the lock block in C# we ensure that only a single thread enters the initialization area.

    public sealed class MultiThreadedSingleton
    {
        private static volatile MultiThreadedSingleton _instance;
        private static object _safeobject = new Object();

        private MultiThreadedSingleton()
        {
       
        }

        public static MultiThreadedSingleton Create()
        {
                 if (_instance == null)
                 {
                    lock (_safeobject)
                    {
                        if (_instance == null)
                        {
                            _instance = new MultiThreadedSingleton();
                        }
                    }
                 }

                    return _instance;
        }

    
    }


No comments:

Post a Comment