Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / C#
Article

Generic Singleton Provider

Rate me:
Please Sign up or sign in to vote.
4.79/5 (22 votes)
26 Jul 20052 min read 147K   57   28
An article describing how to use Generics to create a singleton provider.

Introduction

Many people from different programming backgrounds should be familiar with the Singleton Pattern. Those who use it will find that they often have to write the same code each time they want to create a different Singleton class. With the advent of C# 2.0 Generics, it is possible to write this code only once.

Background

There are many articles about the Singleton Pattern. Probably the most comprehensive one for C# can be found here: "Implementing the Singleton Pattern in C#".

There is an increasing amount written about C# Generics. For example, a CodeProject article can be found here: "Generics in C# 2.0" by Ansil.

Using C# 2.0 Generics to achieve a reusable Singleton pattern

Using C# 2.0 Generics, it is possible to create what I have called a 'Singleton Provider'. This is a class that can be used repeatedly to instantiate a class as a singleton without having to re-write the singleton pattern code for that specific class. This has the added benefit of separating singleton code from the class code leaving the flexibility to use several instances of the class or using the class as a singleton.

The singleton code used in this example is based on the fifth example described in the above article about implementing the Singleton Pattern in C#:

C#
public sealed class Singleton
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return SingletonCreator.instance;
        }
    }

    class SingletonCreator
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

With an understanding of Generics, you can see that there should be no reason to replace the type arguments in this block of code with the typical 'T' found in Generics. If this is done, the code looks like this.

C#
public class SingletonProvider <T> where T:new()
{
    SingletonProvider() {}

    public static T Instance
    {
        get { return SingletonCreator.instance; }
    }

    class SingletonCreator
    {
        static SingletonCreator() { }

        internal static readonly T instance = new T();
    }
}

Note that the Generics must have a constraint on it. This constraint forces any type 'T' to have a default constructor, that is, a constructor that takes no parameters. This allows the SingletonCreator to instantiate the type 'T'.

So, how does one use the SingletonProvider? To understand how to use this, we need a test class. The test class has two features. The first is a default constructor that sets a timestamp member variable. The second is a public method that writes that timestamp using Debug.WriteLine. This setup means that no matter which thread uses this class in the Singleton Pattern, whenever that public method is called, it should output the same value.

C#
public class TestClass
{
    private string _createdTimestamp;

    public TestClass ()
    {
        _createdTimestamp = DateTime.Now.ToString();
    }

    public void Write()
    {
        Debug.WriteLine(_createdTimestamp);
    }
}

The class is used with the SingletonProvider as follows:

C#
SingletonProvider<TestClass>.Instance.Write();

Points of Interest

I have tested this code with a Dual Processor with hyper-threading enabled with 100 threads accessing the singleton. They all output the same value illustrating that this is a thread-safe generic way to create singletons.

I believe that this is a really neat illustration of how Generics can save you writing code.

History

This is the first iteration of this code, please provide any feedback as to whether you have used this or not or any problems that anyone has found with it!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I have been developing primarily with .NET for over 10 years now although I have previous experience with Java and C++.

And no, this isn't a recent picture Smile | :)

Comments and Discussions

 
GeneralUsing this on Forms Pin
Danny.Su2-Mar-07 5:24
Danny.Su2-Mar-07 5:24 
GeneralRe: Using this on Forms Pin
adgonz10-May-07 7:43
adgonz10-May-07 7:43 
AnswerRe: Using this on Forms Pin
Lusid Insanity14-May-07 9:41
Lusid Insanity14-May-07 9:41 
GeneralRe: Using this on Forms Pin
ggeurts14-May-07 22:57
ggeurts14-May-07 22:57 
GeneralRe: Using this on Forms Pin
Danny.Su21-May-07 16:36
Danny.Su21-May-07 16:36 
AnswerRe: Using this on Forms Pin
ggeurts22-May-07 5:47
ggeurts22-May-07 5:47 
Questionusing SingletonProvider to create types on the fly Pin
Jonathan Karlen5-Feb-07 5:43
Jonathan Karlen5-Feb-07 5:43 
AnswerRe: using SingletonProvider to create types on the fly Pin
Mercede18-Jul-08 21:12
Mercede18-Jul-08 21:12 
Creating types on the fly simply means extremely bad design. I cant think of any situation that requires you creating types on the fly. If still you are in need of such then you can try this:
declare the Singleton classes for every class you may require and use a switch statement to decide which one to instantiate
GeneralPointer to article where private on test class will prevent instantiation and force Singleton Pin
Wray Smallwood29-Nov-06 4:36
Wray Smallwood29-Nov-06 4:36 
QuestionThis way prevents a class being instantiated at all Pin
crellbar20-Apr-06 5:13
crellbar20-Apr-06 5:13 
AnswerRe: This way prevents a class being instantiated at all Pin
Stefan Prodan13-Nov-06 5:13
Stefan Prodan13-Nov-06 5:13 
AnswerRe: This way prevents a class being instantiated at all Pin
Yuri Astrakhan24-Apr-07 14:45
Yuri Astrakhan24-Apr-07 14:45 
AnswerRe: This way prevents a class being instantiated at all Pin
radioman.lt2-Oct-07 20:51
radioman.lt2-Oct-07 20:51 
GeneralApp Domains Pin
monsteroftheid4-Aug-05 4:21
monsteroftheid4-Aug-05 4:21 
Generalsingletoncreator Pin
Keith Farmer26-Jul-05 9:33
Keith Farmer26-Jul-05 9:33 
GeneralRe: singletoncreator Pin
davojc26-Jul-05 23:10
davojc26-Jul-05 23:10 
GeneralRe: singletoncreator Pin
Leonardo Pessoa27-Jul-05 2:09
Leonardo Pessoa27-Jul-05 2:09 
GeneralRe: singletoncreator Pin
davojc27-Jul-05 2:12
davojc27-Jul-05 2:12 
GeneralRe: singletoncreator Pin
Richard Deeming28-Jul-05 8:35
mveRichard Deeming28-Jul-05 8:35 
GeneralRe: singletoncreator Pin
Goran Mitrovic27-Jul-05 20:55
Goran Mitrovic27-Jul-05 20:55 
GeneralRe: singletoncreator Pin
davojc27-Jul-05 22:31
davojc27-Jul-05 22:31 
GeneralInteresting Pin
S. Senthil Kumar26-Jul-05 5:47
S. Senthil Kumar26-Jul-05 5:47 
GeneralRe: Interesting Pin
davojc26-Jul-05 22:56
davojc26-Jul-05 22:56 
GeneralRe: Interesting Pin
davojc26-Jul-05 23:47
davojc26-Jul-05 23:47 
GeneralRe: Interesting Pin
mSerg2-Aug-05 21:37
mSerg2-Aug-05 21:37 

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.