Click here to Skip to main content
Click here to Skip to main content

Generic Singleton Provider

, 26 Jul 2005
Rate this:
Please Sign up or sign in to vote.
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#:

    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.

    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.

    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:

    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

Share

About the Author

davojc
Web Developer
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++.
 
Programming is very much only a work task. I rarely do anything programming related in my spare time.
 
And no, this isn't a recent picture Smile | :)

Comments and Discussions

 
GeneralUsing this on Forms Pinmembernothinking2-Mar-07 6:24 
GeneralRe: Using this on Forms PinmemberAntonio David Gonzlez10-May-07 8:43 
AnswerRe: Using this on Forms PinmemberLusid Insanity14-May-07 10:41 
GeneralRe: Using this on Forms Pinmemberggeurts14-May-07 23:57 
GeneralRe: Using this on Forms Pinmembernothinking21-May-07 17:36 
AnswerRe: Using this on Forms Pinmemberggeurts22-May-07 6:47 
Questionusing SingletonProvider to create types on the fly PinmemberJonathan Karlen5-Feb-07 6:43 
AnswerRe: using SingletonProvider to create types on the fly Pinmembermercede18-Jul-08 22:12 
GeneralPointer to article where private on test class will prevent instantiation and force Singleton PinmemberWray Smallwood29-Nov-06 5:36 
QuestionThis way prevents a class being instantiated at all Pinmembercrellbar20-Apr-06 6:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 26 Jul 2005
Article Copyright 2005 by davojc
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid