Click here to Skip to main content
15,867,141 members
Articles / Programming Languages / C#

A Reusable Base Class for the Singleton Pattern in C#

Rate me:
Please Sign up or sign in to vote.
4.71/5 (21 votes)
5 Apr 2013CPOL3 min read 127.4K   54   58
This article presents a reusable base class for implementing singletons in C#.

Introduction

Let's face it: everybody loves singletons! Over the past few years I used a lot of these little buggers throughout all my projects. Recently I became tired of all the "copy & paste" and decided to write a reusable singleton base class for all my projects to come. Today I want to share the fruits of my work with you folks.

Background

The purpose of this base class is to reduce the coding effort when creating a new singleton to an absolute minimum. That does not only mean less finger-tiring coding work for you, but also makes your singletons much more readable and maintainable.

This base class is also thread safe, which is an important thing when it comes to singletons.

Using the code 

The code I'm presenting today consists of two classes:

  • SingletonBase is the base class, that every singleton will derive from.
  • SingletonExample is a very simple singleton, that shows how to derive from the base class.

And that's it. All of it. Pretty simple, huh? Now let's dive right in!

The example singleton 

I'll start by putting the cart before the horse. The code below shows a very simple singleton class that derives from our magic singleton base class (which will be shown later).

C#
/// <summary>
/// This class is an example of how to create a singleton based on the singleton base class.
/// </summary>
class SingletonExample : SingletonBase<SingletonExample>
{
  /// <summary>
  /// Gets or sets a string property.
  /// </summary>
  public string SomeString {get; set; }
 
  /// <summary>
  /// Initializes a new instance of the <see cref="Singleton"/> class.
  /// </summary>
  private SingletonExample()
  {
  }
}

Here are the three important points to learn from the example above:

  • The singleton derives from our base class SingletonBase.
  • We pass the singleton's class name as a type parameter (SingletonBase<SingletonExample>)).
  • We define a private constructor. This is important since we don't want anyone to actually instantiate our singleton.

As you can see the singleton itself is super-simple. All of the heavy lifting is done by the base class. So you can concentrate on implementing all those fancy methods and properties you have always dreamed of.

The singleton base class

Now let's get to the good stuff: our magic singleton base class!  Here we want to make sure that only one instance of our singleton exists at a time. And we want to do so in a thread safe way. Let's get there step by step:

C#
public abstract class SingletonBase<T> where T : class
{
  ...

Here we declare our singleton base class. As you can see this is a template class (that's where Mr. "T" comes from). This allows us to pass in the singleton's class as a type parameter (see the example above).

Next we have to answer an important question: how does the user access the singleton's instance? This problem is usually solved by providing a property called "Instance" (very creative, right?). This property returns the one and only instance of our singleton. Here's how we implement that:

C#
/// <summary>
/// Static instance. Needs to use lambda expression
/// to construct an instance (since constructor is private).
/// </summary>
private static readonly Lazy<T> sInstance = new Lazy<T>(() => CreateInstanceOfT());

/// <summary>
/// Gets the instance of this singleton.
/// </summary>
public static T Instance { get { return sInstance.Value; } }

I think the above lines of code deserve a little bit of explanation. First of all there is an static member called "sInstance". It holds the instance of our singleton, and is lazily initialized. This is comfortably achieved by using .NET 4.0's Lazy<T> class. And the best thing is: Lazy<T> is fully thread safe!

The second thing to notice is the mysterious method called "CreateInstanceOfT". Why do we need that? Why not simply call new? Well, that's due to the fact that our singleton has a private constructor (if you have forgotten, just scroll up a little bit to our SingletonExample class). Because of this we have to resort to a little trick: the Activator!

C#
/// <summary>
/// Creates an instance of T via reflection since T's constructor is expected to be private.
/// </summary>
/// <returns></returns>
private static T CreateInstanceOfT()
{
  return Activator.CreateInstance(typeof(T), true) as T;
}

With the help of this little method we can now instantiate our singleton class, although its constructor is private. Neat, huh?

The whole singleton base class

And that's it! Now you've seen the whole singleton base class. Here's what all those bits look like put together to a complete class, ready for copy & paste:

C#
/// <summary>
/// A base class for the singleton design pattern.
/// </summary>
/// <typeparam name="T">Class type of the singleton</typeparam>
public abstract class SingletonBase<T> where T : class
{
  #region Members

  /// <summary>
  /// Static instance. Needs to use lambda expression
  /// to construct an instance (since constructor is private).
  /// </summary>
  private static readonly Lazy<T> sInstance = new Lazy<T>(() => CreateInstanceOfT());

  #endregion

  #region Properties

  /// <summary>
  /// Gets the instance of this singleton.
  /// </summary>
  public static T Instance { get { return sInstance.Value; } }

  #endregion

  #region Methods

  /// <summary>
  /// Creates an instance of T via reflection since T's constructor is expected to be private.
  /// </summary>
  /// <returns></returns>
  private static T CreateInstanceOfT()
  {
    return Activator.CreateInstance(typeof(T), true) as T;
  }

  #endregion
}

Points of Interest 

As you might have noticed the Lazy<T> class is only available in .NET 4.0 and higher. If you are somehow forced by a higher power to use .NET versions below that, this code is not for you. Sorry!

History

I've rewritten the method CreateInstanceOfT based on the comments below. As people pointed out to me the Activator is faster than reflection when it comes to instantiating objects.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionSingletons and Thread Safety Pin
David A. Gray1-Aug-21 21:03
David A. Gray1-Aug-21 21:03 
GeneralMy vote of 5 Pin
David A. Gray1-Aug-21 20:43
David A. Gray1-Aug-21 20:43 
QuestionConstructor with arguments Pin
febo7413-Apr-20 6:29
febo7413-Apr-20 6:29 
Question5 Pin
#realJSOP4-Apr-20 23:52
mve#realJSOP4-Apr-20 23:52 
Questionupdated code for standardizations Pin
Member 140096135-Oct-18 21:07
Member 140096135-Oct-18 21:07 
Suggestionthis actually works 1 Pin
Member 140096135-Oct-18 20:27
Member 140096135-Oct-18 20:27 
Questionderived class Pin
Member 339579429-Jul-14 9:19
Member 339579429-Jul-14 9:19 
QuestionException: Pin
CCB201013-Nov-13 10:17
CCB201013-Nov-13 10:17 
AnswerRe: Exception: Pin
Kees van Spelde24-Jan-15 5:12
professionalKees van Spelde24-Jan-15 5:12 
GeneralRe: Exception: Pin
Member 1242634630-Mar-16 6:08
Member 1242634630-Mar-16 6:08 
AnswerRe: Exception: Pin
#realJSOP4-Apr-20 23:51
mve#realJSOP4-Apr-20 23:51 
GeneralMy vote of 5 Pin
_Nizar19-Aug-13 2:36
_Nizar19-Aug-13 2:36 
Questionfull defination of SingletonExample Pin
shah jony22-May-13 20:51
shah jony22-May-13 20:51 
AnswerRe: full defination of SingletonExample Pin
Boris Brock11-Jun-13 21:24
Boris Brock11-Jun-13 21:24 
GeneralMy vote of 5 Pin
Member 84402889-Apr-13 2:21
Member 84402889-Apr-13 2:21 
QuestionSingleton Pin
geoyar8-Apr-13 9:20
professionalgeoyar8-Apr-13 9:20 
AnswerRe: Singleton Pin
Boris Brock8-Apr-13 21:58
Boris Brock8-Apr-13 21:58 
GeneralRe: Singleton Pin
geoyar9-Apr-13 8:44
professionalgeoyar9-Apr-13 8:44 
Do you know why? What does make it atomic?
What a magic bullet are they using?
Why is it impossible to use the same technique in C++?
geoyar

GeneralRe: Singleton Pin
teejay879-Apr-13 21:31
teejay879-Apr-13 21:31 
GeneralRe: Singleton Pin
geoyar10-Apr-13 10:27
professionalgeoyar10-Apr-13 10:27 
GeneralRe: Singleton Pin
teejay8710-Apr-13 21:17
teejay8710-Apr-13 21:17 
GeneralRe: Singleton Pin
geoyar11-Apr-13 9:28
professionalgeoyar11-Apr-13 9:28 
QuestionI don't like singleton Pin
Giuseppe Tollini5-Apr-13 8:31
Giuseppe Tollini5-Apr-13 8:31 
Suggestionsome thoughts and missing multithreading Pin
Thomas Haller5-Apr-13 6:00
Thomas Haller5-Apr-13 6:00 
GeneralRe: some thoughts and missing multithreading Pin
Boris Brock7-Apr-13 21:11
Boris Brock7-Apr-13 21:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.