Click here to Skip to main content
15,891,657 members
Articles / Programming Languages / C#

Yet Another Singleton Implementation in .NET 2.0

Rate me:
Please Sign up or sign in to vote.
1.11/5 (6 votes)
14 Feb 2010CPOL3 min read 27.1K   98   6   11
Simple and easy Singleton pattern implemented in .NET 2.0

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

  • ChoStrictSingleton<T> - It will checks and verifies the type to have only private constructors.

  • ChoSingleton<T> - It will checks and verify the type to have either private or protected constructors.

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 //Below two calls should go through fine
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 //Below call should go through fine
2 Console.WriteLine(ChoSingleton<ClassWithProtectedCtor>.Instance(2001));
3 //Below call will throw an exception for having protected constructor
4 Console.WriteLine(ChoStrictSingleton<ClassWithProtectedCtor>.Instance(2001)); // <-- Exception will be raised

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 //Below two calls will throw an exception for having public constructor
2 Console.WriteLine(ChoSingleton<ClassWithPublicCtor>.Instance(3000));          // <-- Exception will be raised
3 Console.WriteLine(ChoStrictSingleton<ClassWithPublicCtor>.Instance(3001));    // <-- Exception will be raised

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());          // <-- Exception raised

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.

License

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



Comments and Discussions

 
GeneralMy vote of 1 Pin
Steve Hansen16-Feb-10 3:16
Steve Hansen16-Feb-10 3:16 
GeneralMy vote of 1 Pin
John Brett15-Feb-10 4:25
John Brett15-Feb-10 4:25 
GeneralMy vote of 1 Pin
paragme14-Feb-10 18:28
paragme14-Feb-10 18:28 
GeneralMy vote of 2 Pin
Omer Mor14-Feb-10 8:25
Omer Mor14-Feb-10 8:25 
GeneralSingletons are Evil - don't (ab)use it Pin
Omer Mor14-Feb-10 8:19
Omer Mor14-Feb-10 8:19 
Just Google "singletons are evil" and read the countless explanations.
GeneralRe: Singletons are Evil - don't (ab)use it Pin
User 112731714-Feb-10 12:01
User 112731714-Feb-10 12:01 
GeneralMy vote of 1 Pin
SledgeHammer0114-Feb-10 8:03
SledgeHammer0114-Feb-10 8:03 
Generaluse the keyword 'volatile' Pin
reborn_zhang14-Feb-10 7:13
reborn_zhang14-Feb-10 7:13 
GeneralRe: use the keyword 'volatile' Pin
User 112731714-Feb-10 12:10
User 112731714-Feb-10 12:10 
GeneralMy vote of 1 Pin
Puchko Vasili14-Feb-10 3:49
Puchko Vasili14-Feb-10 3:49 
GeneralThat is not a singleton! Pin
PIEBALDconsult14-Feb-10 3:10
mvePIEBALDconsult14-Feb-10 3:10 

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.