Click here to Skip to main content
15,878,809 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Usage of singleton wrapper for better coding

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
24 Jan 2013CPOL1 min read 20.2K   14   2
More advanced singleton implementation.

Introduction 

In this short tip I want to introduce to the community my implementation of a singleton wrapper. So let's begin.

Background

Recently I discovered an article (link) which was written by Sir Schamese. In his post he shows his implementation of the singleton pattern. But this implementation lacks lazy initialization. So I decided to implements a singleton by myself.

Code implementation 

When .NET 4.0 was released many developers discovered a useful primitive type called Lazy<T>.

Besides lazy initialization capabilities, Lazy<T> has another use, which is related to thread-safety. Being a developer who has been doing multithreading almost each day, I noticed that class was very useful for myself.

We can use lazy initialization to defer the creation of a large or resource-intensive object, or the execution of a resource-intensive task, particularly when such a creation or execution might not occur during the lifetime of the program. 

So I'm going to show you my singleton wrapper which under the hood uses Lazy<T>.

C#
public abstract class SingletonBase<T> where T : class
{
    private static readonly Lazy<T> _Lazy = new Lazy<T>(() =>
    {
        // Get non-public constructors for T.
        var ctors = typeof(T).GetConstructors(System.Reflection.BindingFlags.Instance | 
                                  System.Reflection.BindingFlags.NonPublic);
        if (!Array.Exists(ctors, (ci) => ci.GetParameters().Length == 0))
            throw new InvalidOperationException("Non-public ctor() was not found."); 
        var ctor = Array.Find(ctors, (ci) => ci.GetParameters().Length == 0);
        // Invoke constructor and return resulting object.
        return ctor.Invoke(new object[] { }) as T;
    }, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
    public static T Instance
    {
        get
        {
            return _Lazy.Value;
        }
    }
}

So for making any class behavior like singleton, let's do this:

C#
public class MySingleton: SingletonBase<MySingleton>
{
  private MySingleton(){ }
}

As a result our class called MySingleton will inherit singleton behavior.

Caution: An important moment, if you didn't provide any private ctor in your class, an InvalidOperationException will be thrown!!!

I strongly recommend you use lazy initialization in case your objects can be heavy in memory allocation (allocation of resources), or when you are sure that an object can not be used by a program for some reason.  

So what do we gain with such implementation ? 

  • thread safety
  • lazy initialization

Hope you will find this tip/trick helpful for yourself and you will use it in your projects. Happy coding for all of you Wink | ;)

License

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


Written By
Team Leader Delphi LLC
Ukraine Ukraine
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Klaus Luedenscheidt24-Jan-13 18:46
Klaus Luedenscheidt24-Jan-13 18:46 
GeneralRe: My vote of 5 Pin
Oleksandr Kulchytskyi24-Jan-13 21:08
professionalOleksandr Kulchytskyi24-Jan-13 21:08 

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.