Introduction
Many of you aware what is Singleton Pattern is. For whom don't know what is
Singleton pattern is? Please visit this
http://www.dofactory.com/Patterns/PatternSingleton.aspx
link. Many programmers would implemented and used singleton class in their life.
Also may come across different types implementation and details from various
sites as well.
What I'm posting here is 'Yet another implementation of Singleton pattern'. But
it is simple and clean. Uses .NET reflection heavily. Yes, I agree with
performace impact on using reflection. Of course it is a trade-off in using
reflection. But it has great flexibility in absracting some common
functionalities and help reducing code bloat.
The singleton provider classes imposes the below checks/rules on the passing
singleton types
-
Must be 'sealed' class
-
Make sure the type have no 'static' members (exception are the factory method -
will talk about that later.)
-
Making sure the type have only one private / protected constructors (otherwise
you decorated with ChoSingletonConstructorAttribute - Will talk about that
later.)
This framework exposes two singleton provider classes
PS: Please turn on Reflection Permission in order to use this framework.
How to use
A. Standard Singleton Type Approch
In this section, I'll discuss how to use this framework to create Singleton class
and its instance in a standard way.
Let assume, you have a base class defined as below
1 [DebuggerDisplay("Info = {ToString()}")]
2 public class BaseClass
3 {
4 public int Id;
5 public string Name;
6
7 protected BaseClass(int id, string name)
8 {
9 Id = id;
10 Name = name;
11 }
12
13 public override string ToString()
14 {
15 return String.Format("Id: {0}, Name: {1}", Id, Name);
16 }
17 }
1. Class with a Private Constructor.
The simplest and straight way to create Singleton class is
1 public sealed class ClassWithPrivateCtor : BaseClass
2 {
3 private ClassWithPrivateCtor(int id)
4 : base(id, typeof(ClassWithPrivateCtor).Name)
5 {
6 }
7 }
Here is the way to create a singleton instance as below
1
2 Console.WriteLine(ChoSingleton<ClassWithPrivateCtor>.Instance(1000));
3 Console.WriteLine(ChoStrictSingleton<ClassWithPrivateCtor>.Instance(1001));
2. Class with a Protected Constructor.
The simplest and straight way to create Singleton class is
1 public sealed class ClassWithProtectedCtor : BaseClass
2 {
3 protected ClassWithProtectedCtor(int id)
4 : base(id, typeof(ClassWithProtectedCtor).Name)
5 {
6 }
7 }
Here is the way to create a singleton instance as below
1
2 Console.WriteLine(ChoSingleton<ClassWithProtectedCtor>.Instance(2001));
3
4 Console.WriteLine(ChoStrictSingleton<ClassWithProtectedCtor>.Instance(2001));
3. Class with a Public Constructor.
The simplest and straight way to create Singleton class is
1 public sealed class ClassWithPublicCtor : BaseClass
2 {
3 public ClassWithPublicCtor(int id)
4 : base(id, typeof(ClassWithPublicCtor).Name)
5 {
6 }
7 }
Here is the way to create a singleton instance as below
1
2 Console.WriteLine(ChoSingleton<ClassWithPublicCtor>.Instance(3000));
3 Console.WriteLine(ChoStrictSingleton<ClassWithPublicCtor>.Instance(3001));
4. Class with a Private Default Constructor.
The simplest and straight way to create Singleton class is
1 public sealed class ClassWithDefaultCtor : BaseClass
2 {
3 private ClassWithDefaultCtor()
4 : base(4000, typeof(ClassWithDefaultCtor).Name)
5 {
6 }
7 }
Here is the way to create a singleton instance as below
1 Console.WriteLine(ChoSingleton<ClassWithDefaultCtor>.Instance());
5. Class with a Private Non-Default Constructor.
The simplest and straight way to create Singleton class is
1 public sealed class ClassWithNoDefaultCtor : BaseClass
2 {
3 private ClassWithNoDefaultCtor(int id)
4 : base(id, typeof(ClassWithNoDefaultCtor).Name)
5 {
6 }
7 }
Here is the way to create a singleton instance as below
1 Console.WriteLine(ChoSingleton<ClassWithNoDefaultCtor>.Instance(5000));
B. Custom Singleton Type Approch
In this section, I'll discuss how to use this framework to create Singleton class
and its instance in non-standard way. It is very less likely you will have use
approch.
You can use this approch when you have the below situations
- Your singleton type ends up having multiple private/protected constructors and
you want to switch and use them while creating Singleton instance. In this case,
you can decorate that particular constructor with
[ChoSingletonConstructorAttribute], Framework will use that constructor to
create the singleton instance for you.
- Your singleton type needs to perform some custom action before creating
singleton instance. In this case, you can define a factory method (should be
static method) and decorate that method with
[ChoSingletonFactoryMethodAttribute]. Framework will use this method to create a
singleton instance for you.
In the above both cases, the Singleton type should be decorated with
[ChoCustomSingletonTypeAtrribute]. Otherwise the framework will complain with
errors.
1. Create Singleton Instance with particular constructor.
If you define a class with multiple private constructors as below, you have
specify one of them with ChoSingletonConstructorAttribute in order to reveal it
to the framework to use it while creating singleton instance.
1 [ChoCustomSingletonType]
2 public sealed class ClassToCallParticularCtor : BaseClass
3 {
4 private ClassToCallParticularCtor()
5 : base(6000, typeof(ClassToCallParticularCtor).Name)
6 {
7 }
8
9 [ChoSingletonConstructor]
10 private ClassToCallParticularCtor(int id)
11 : base(id, typeof(ClassToCallParticularCtor).Name)
12 {
13 }
14 }
Here is the way to create a singleton instance as below
1 Console.WriteLine(ChoSingleton<ClassToCallParticularCtor>.Instance(6001));
Below call will throw an exception, as no parameters are passed.
1 Console.WriteLine(ChoSingleton<ClassToCallParticularCtor>.Instance());
2. Create Singleton Instance using Factory Method.
This approch will use the factory method to create a singleton instance.
1 [ChoCustomSingletonType]
2 public sealed class ClassWithFactoryMethod : BaseClass
3 {
4 private ClassWithFactoryMethod()
5 : base(7000, typeof(ClassWithFactoryMethod).Name)
6 {
7 }
8
9 private ClassWithFactoryMethod(int id)
10 : base(id, typeof(ClassWithFactoryMethod).Name)
11 {
12 }
13
14 [ChoSingletonFactoryMethod]
15 private static object CreateInstance(int id)
16 {
17 return new ClassWithFactoryMethod(id);
18 }
19 }
Here is the way to create a singleton instance as below
1 Console.WriteLine(ChoSingleton<ClassWithFactoryMethod>.Instance(7001));
That's all folks. Try it, please do drop your feedback.