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>
.
public abstract class SingletonBase<T> where T : class
{
private static readonly Lazy<T> _Lazy = new Lazy<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);
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:
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