A Generic Singleton Implementation#

The Singleton design pattern is one of the most widely known patterns in the software industry. In .NET 2.0, it's easy to provide a generic implementation of this pattern so you won't ever have to write the code that makes it happen again. Even though there's not much code involved, it can be tricky to get right if you consider thread safety and laziness of instantiation.

If you use the class below, accessing a singleton of any class is as simple as calling Singleton<Foo>.Instance. The Foo type only needs to support a default constructor and never worry about the details of the singleton itself. Here's the implementation of the generic Singleton class:

/// <summary>
/// Provides a global point of access to a single instance of a given class.
/// </summary>
/// <typeparam name="T">The type to provide a singleton instance for.</typeparam>
/// <remarks>
/// <para>
/// The singleton instance can be accessed through a static property,
/// where the type of the singleton is passed as a generic type parameter.
/// Subsequent requests for the instance will yield the same class instance.
/// </para>
/// <note>
/// The singleton is thread-safe and lazy (i.e. it is created when the instance
/// is first requested).
/// </note>
/// </remarks>
/// <example>
/// The following example gets a singleton instance of a <c>Foo</c> class:
/// <code>
/// Foo singleInstance = Singleton<Foo>.Instance;
/// </code>
/// </example>
public static class Singleton<T> where T : new()
{
    /// <summary>
    /// Gets the singleton instance.
    /// </summary>
    public static T Instance
    {
        get
        {
            // Thread safe, lazy implementation of the singleton pattern.
            // See http://www.yoda.arachsys.com/csharp/singleton.html
            // for the full story.
            return SingletonInternal.instance;
        }
    }

    private class SingletonInternal
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit.
        static SingletonInternal()
        {
        }

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

Note the implementation using a private class with an explicit static constructor, this is to provide both the thread safety as the lazy instantiation. More details can be found in the "Implementing the Singleton Pattern in C#" article by Jon Skeet.

Monday, November 14, 2005 11:11:12 AM (Romance Standard Time, UTC+01:00)
I prefer initialising the instance in the static constructor. This allows me to load some config (if needed)
Peter
Monday, November 14, 2005 6:05:18 PM (Romance Standard Time, UTC+01:00)
You can keep doing this in your class that's being "singletoned" without a problem. This class just abstracts away the instance creation and static accessor that both form the Singleton pattern.

Now since there should be only one instance anyway, you can also implement the same logic in your default instance constructor (which gets called by the Singleton class above).
Wednesday, November 16, 2005 5:09:28 PM (Romance Standard Time, UTC+01:00)
With this, you can get a singleton instance of a class, but you can still get any number of other instances of that class. Is the following still threadsafe?

(I have replaced angle brackets with [] to satisfy this web form).

public class MySingletonClass
{
private MySingletonClass() {}

public MySingletonClass Instance
{
get { return Singleton[MySingletonClass].Instance; }
}
}
Patrick Lioi
Thursday, November 17, 2005 9:21:37 AM (Romance Standard Time, UTC+01:00)
Patrick,

Because you need to have a default constructor, you can indeed still have multiple instances of the class since you can new up as many as you want yourself. In that sense, the instancing isn't entirely shielded from the callers. But if you take care to use only the Singleton class to access the instance, you won't have a problem.

The code you provided wouldn't compile since the Singleton class will need a public default constructor and yours is private.
Wednesday, November 29, 2006 5:19:41 PM (Romance Standard Time, UTC+01:00)
See this link for a truly Generic implementation which prevents instantiation http://www.codeproject.com/cs/design/GenericSingletonPattern.asp
Wray Smallwood
Comments are closed.
All content © 2014, Jelle Druyts
On this page
Top Picks
Statistics
Total Posts: 351
This Year: 0
This Month: 0
This Week: 0
Comments: 530
Archives
Sitemap
Disclaimer
This is my personal website, not my boss', not my mother's, and certainly not the pope's. My personal opinions may be irrelevant, inaccurate, boring or even plain wrong, I'm sorry if that makes you feel uncomfortable. But then again, you don't have to read them, I just hope you'll find something interesting here now and then. I'll certainly do my best. But if you don't like it, go read the pope's blog. I'm sure it's fascinating.

Powered by:
newtelligence dasBlog 2.3.12105.0

Sign In