|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article presents a generic class that uses reflection to create a single instance of any class. It can be used to instantiate Singletons from public classes with non-public constructors, and Singletons from non-public classes as well. The main motivation for this solution is to have the Singleton pattern written in only one place, reusable by all classes that need to follow that pattern. BackgroundThere's already a very good article, Implementing the Singleton Pattern in C#, that describes the challenges and caveats of developing a Singleton in .NET; I won't go into the details again. There are also some Singletons using generics here and there (see Generic Singleton Provider as an example), but none was solving the problem of creating a single instance of a class with a non-accessible constructor (something that all Singletons should have). Singleton<T>This is the generic public static class Singleton<T>
where T : class
{
static Singleton()
{
}
public static readonly T Instance =
typeof(T).InvokeMember(typeof(T).Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.NonPublic,
null, null, null) as T;
}
The type parameter
The initialization of the As you can presume, Using Singleton<T>Another best practice of the Singleton pattern is to have every Singleton return its own single instance. This is usually done by a static property named public static SingleInstanceClass Instance
{
get
{
return Singleton<SingleInstanceClass>.Instance;
}
}
DemoThe demo shows the life cycle of the // SingleInstanceClass is a Singleton.
public class SingleInstanceClass
{
// Private constructor to prevent
// casual instantiation of this class.
private SingleInstanceClass()
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("SingleInstanceClass created.");
Console.ResetColor();
_count++;
}
// Gets the single instance of SingleInstanceClass.
public static SingleInstanceClass Instance
{
get { return Singleton<SingleInstanceClass>.Instance; }
}
public static int Count { get { return _count; } }
public static void DoStatic()
{ Console.WriteLine("DoStatic() called."); }
public void DoInstance()
{ Console.WriteLine("DoInstance() called."); }
// Instance counter.
private static int _count = 0;
}
class Program
{
static void Main()
{
// Show that initially the count is 0; calls
// a static property which doesn't create the Singleton.
Console.WriteLine("---");
Console.WriteLine("Initial instance count: {0}",
SingleInstanceClass.Count);
// Similar to above; show explicitly that calling
// a static methods doesn't create the Singleton.
Console.WriteLine("---");
Console.WriteLine("Calling DoStatic()");
SingleInstanceClass.DoStatic();
Console.WriteLine("Instance count after DoStatic(): {0}",
SingleInstanceClass.Count);
// Show that getting the instance creates the Singleton.
Console.WriteLine("---");
Console.WriteLine("Calling DoInstance()");
SingleInstanceClass.Instance.DoInstance();
Console.WriteLine("Instance count after first DoInstance(): {0}",
SingleInstanceClass.Count);
// Show that getting the instance
// again doesn't re-instantiate the class.
Console.WriteLine("---");
Console.WriteLine("Calling DoInstance()");
SingleInstanceClass.Instance.DoInstance();
Console.WriteLine("Instance count after second DoInstance(): {0}",
SingleInstanceClass.Count);
Console.ReadKey();
}
}
The program output is:
ConclusionThere are many ways to implement the Singleton pattern in C#.
|
||||||||||||||||||||||