Pattern Name:

Singleton Pattern

Short Description:

Class with only one single possible instance

Usage:

Often used for objects that need to provide global access with the constraint of only one single instance in the application

Complexity:

1 / 5

UML Class Diagram:

image_thumb2_thumb[2]

Explanation:

  • There are multiple ways of implementing the Singleton Pattern in C#. I am going to explain the most efficient approaches that also provide thread safety.
  • Note that in the first example the default constructor is defined as private so that it is not possible to instantiate the object from the outside. The class is also marked as sealed which means that inheritance is not allowed for it.
  • The internally instantiated object is stored in a private variable that is marked as static. The public static property GetInstance is used to allow access to this object. It contains the business logic that assures that only a single instance can ever exist.
  • To achieve this behavior a lock strategy is used to assure that only a single thread is allowed to do the null check and create a new instance if it does not already exist.
  • A test function DisplayConfiguration() was added to be able to verify the class design.
    public sealed class ConfigurationManager
    {
        private static ConfigurationManager instance;
        private static object syncRoot = new Object();

        private ConfigurationManager()
        {
       
        }

        public static ConfigurationManager GetInstance
        {
            get
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new ConfigurationManager();
                    }
                }

                return instance;
            }
        }

        public void DisplayConfiguration()
        {
            Console.WriteLine("Single instance object");
        }
    }
  • Note that in the second example the default constructor is also defined as private so that it is not possible to instantiate the object from the outside. The class is also marked as sealed which means that inheritance is not allowed for it.
  • This time a private nested class is used to provide access to the instance that must only exist once in the application.
  • This nested class has a static default constructor and an internal static read-only instance of the object. Only the container class has access to the instance which will due to the software design (auto-instantiated and marked as read-only) only exist once.
  • A test function DisplayRules() was added to be able to verify the class design.
  • I recommend using this example as your default approach for your Singleton implementations since there is no locking in it which makes it more efficient in terms of performance.
    public sealed class BusinessRulesManager
    {
        private BusinessRulesManager()
        {

        }

        public static BusinessRulesManager GetInstance
        {
            get
            {
                return BusinessRulesManagerImpl.instance;
            }
        }

        public void DisplayRules()
        {
            Console.WriteLine("Single instance object");
        }

        private class BusinessRulesManagerImpl
        {
            static BusinessRulesManagerImpl()
            {

            }

            internal static readonly BusinessRulesManager instance = new BusinessRulesManager();
        }
    }
  • In the last step we add some code to test the software design and the Singleton implementation.
    private static void Singleton()
    {
        var configurationManager = ConfigurationManager.GetInstance;
        configurationManager.DisplayConfiguration();

        var businessRulesManager = BusinessRulesManager.GetInstance;
        businessRulesManager.DisplayRules();

        Console.ReadKey();
    }
  • When running the example you can see that everything is working as expected (it is however not as simple to test that there really is just one single instance, you just have to believe in the correct software design).

image_thumb_thumb[1]

Last edited May 28, 2011 at 7:10 PM by JasonOliveira, version 1

Comments

ksabada Apr 8, 2015 at 5:21 PM 
namespace DesignPatterns2010
{
public sealed class SingletonPattern
{
static SingletonPattern singletonObject;
static object _object = new object();

public static SingletonPattern GetObject
{
get
{
lock (_object)
{
if (singletonObject == null)
singletonObject = new SingletonPattern();
}
return singletonObject;
}
}

private SingletonPattern()
{

}

public int CallFunction(int category,int param1,int param2)
{
int result = 0;
switch (category)
{
case 1:
result = GetSum(param1,param2);
break;
case 2:
result = GetSubtract(param1, param2);
break;
}

return result;
}

private static int GetSum(int a, int b)
{
return a + b;
}

public static int GetSubtract(int a, int b)
{
return a - b;
}
}
}

SingletonPattern singleton1 = SingletonPattern.GetObject;
SingletonPattern singleton2 = SingletonPattern.GetObject;

FactoryPattern f1 = new FactoryPattern();
FactoryPattern f2 = new FactoryPattern();

if (singleton1 == singleton2)
{
int add = singleton1.CallFunction(1,10, 20);
int minus = singleton1.CallFunction(2, 10, 20);

Console.WriteLine("Add = {0}", add);
Console.WriteLine("Minus = {0}", minus);
Console.ReadKey();
}

jtwine Jul 24, 2014 at 6:59 PM 
Not sure if anyone cares, given the nature of how things are being updated, but the .NET 4.0 Lazy<T> type makes this much easier and gives you thread safety:

```
public static class Singleton
{
private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>( () => new Singleton() );

public static Singleton Instance
{
get
{
return( lazy.Value );
}
}
private Singleton()
{
}
}
```

zhusong Jan 1, 2014 at 8:37 AM 
Example One - better to have another null check before the lock statement to avoid non-null instance waiting to entry the Critical Section which is no need
public static ConfigurationManager GetInstance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new ConfigurationManager();
}
}

return instance;
}
}
}

Example Two - no need to bother adding a private class, following code would suffice,
private static readonly BusinessRulesManager instance = new BusinessRulesManager();
public static BusinessRulesManager GetInstance
{
get
{
return instance;
}
}

Arjay Mar 12, 2013 at 12:32 AM 
The scope of the lock should be increased to include the return portion of the get statement on the GetInstance property.

public static ConfigurationManager GetInstance
{
get
{
lock (syncRoot)
{
if (instance == null)
{
instance = new ConfigurationManager();
}
return instance;
}
}
}

w3schools Jul 17, 2012 at 5:45 PM 
nice