Singleton Pattern
Quite awhile back I posted about how to create a re-usable singleton pattern in .Net. Link is here. A bit of time has passed and I've altered the pattern a bit. The reasons for the change are some new type inference patterns and FxCop cleanliness.
The first pattern I introduced had a couple of FxCop violations. Namely Microsoft.Design CA1000 - Do not declare static members on generic types. The logic here being that static methods don't have any type inference benefits as you must explicitly add the type into the name of the type you were using (in this case Singleton).
Secondly because T was at a class level rather than a method level I couldn't have granualar methods which had differing set of constraints. The result was a pattern that was not always easy to write out.
The new pattern takes care of both of these problems. It has two methods. One of which can be satisfied with a trivial lambda expression. The other can easily be used for classes that satisfy the generic constraint new() with no additional lambda.
class c1
{
public static c1 Instance1
{
get { return Singleton.GetInstance(() => new c1());}
}
public static c1 Instance2
{
get { return Singleton.GetInstance<c1>(); }
}
public c1()
{
}
}
Below is the new singleton pattern.
public delegate T Operation<T>();
/// <summary>
/// Used for classes that are single instances per appdomain
/// </summary>
public static class Singleton
{
private static class Storage<T>
{
internal static T s_instance;
}
[SuppressMessage("Microsoft.Reliability", "CA2002")]
public static T GetInstance<T>(Operation<T> op)
{
if (Storage<T>.s_instance == null)
{
lock (typeof(Storage<T>))
{
if (Storage<T>.s_instance == null)
{
T temp = op();
System.Threading.Thread.MemoryBarrier();
Storage<T>.s_instance = temp;
}
}
}
return Storage<T>.s_instance;
}
public static T GetInstance<T>()
where T : new()
{
return GetInstance(() => new T());
}
}
#endregion
}
Edit: Originally forgot to add the signature for Operation<T>
Comments
Anonymous
September 04, 2007
Have you looked at these examples? http://geekswithblogs.net/decclestone/archive/2005/12/22/63925.aspx It has a much more simplified version and runs much faster due to avoiding a critical section. I'm not exact sure how the two techniques could be merged.Anonymous
September 04, 2007
Ok, now I think I understand why you are using the double locking technique. Operation<T> is not valid wrt System.Web.Services.Description namespace.Anonymous
September 04, 2007
This all seems rather silly to me. Unless you have a requirement that you have to support more than one implementation, you can just use a Module/static class and side-step all this locking nonsense.