Snippet

The Singleton design pattern is one of the original Gang of Four design patterns. It is designed to limit the number of instances of a class to just one.

When would you want to use this? In fact, the scenario is quite common. Suppose you have a class, we'll call it CurrentUsers that keeps track of the currently logged users. The Singleton ensures there will only be one instance at any point in time.

Not using a Singleton in the above scenario could lead to duplicate trackers and all kinds of wrong information.

Here is an example of the simplest possible Singleton class:

public class Singleton
{
   private static Singleton instance;

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new Singleton();
         }
         return instance;
      }
   }
}

Notice the class maintains a reference to itself with the static instance variable.

Next notice the private constructor. This prevents anyone from creating an instance of Singleton and the following line will create a compiler error:

var singleton = new Singleton(); 

The only way to access this class in the application is with the following code:

var singleton = Singleton.Instance;

This class demonstrates another pattern: the Lazy Load pattern. The instance is only created when it is really needed. You can see how this works in this block:

if (instance == null)
{
    instance = new Singleton();
}
return instance;

Finally, here is a simple example of the CurrentUsers Singleton:

public class CurrentUsers
{
   private static CurrentUsers instance;

   private CurrentUsers() {}

   public static CurrentUsers Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new CurrentUsers();
         }
         return instance;
      }
   }

   // Anything that the class does goes here

   private static List<User> users {get; set;} = new List<User>();

   public void Add(User user)
   {
       users.Add(user);
   }

   public void Remove(User user)
   {
       users.Remove(user);
   }

   public GetAll()
   {
       return users;
   }
}
1 Replies

Actually the above example is not thread-safe!

Here is a better, thread-safe way to implement the Singleton pattern:

public sealed class Singleton
{
    private Singleton() {  }

    public static Singleton Instance { get; } = Inner.Instance;

    private class Inner
    {
        static Inner() { } // prevents compiler from setting 'beforefieldinit'

        internal static readonly Singleton Instance = new Singleton();
    }
}

This is quite an elegant implementation because it does not require explicit locking.