Singletons

Singletons

The singleton pattern is probably one of the most overused design approaches of all times. Still, there are times when it actually makes sense to take that approach. Because of that, I have a base class for creating singleton classes with. Here is the listing for that class:

public abstract class SingletonBase<T>
    where T : SingletonBase<T>
{
    private static T _instance;
    public static T Instance()
    {
        if (_instance == null)
        {
            _instance = Activator.CreateInstance(typeof(T), true) as T;
        }
        return _instance;
    }
}

Not really much going in there. The class accepts a generic type T, that allows me to specify the type of the eventual instance. This makes it easier to use with classes that implement an associated interface – an approach I use quite often.

The static Instance method checks to see if the _instance variable, which is of type T, contains a reference, or not. If not, I use the Activator to create the object instance with, casting the result as an object of type T.

Using this class is simple. Here is what I usually do. Assuming I only have one type, in this case a class called MyType:

public sealed class MyClass : SingletonBase<MyClass>
{
   private MyClass() {}
}

This produces a singleton type, MyClass, with a single, static, public method called Instance, that returns the singleton MyClass object.

Assuming I have two types, an interface and a class, this is how I usually do things:

public interface IMyClass {}
public sealed class MyClass : SingletonBase<IMyClass>, IMyClass
{
   private MyClass() {}
}

That produces a singleton type, MyClass, that implements the interface IMyType, with a single, static, public method called Instance, that returns the singleton IMyClass object.

Sharp eyed readers will notice my use of a private constructor (ctor) in each example. That’s just the reality of C#. If I don’t put a private ctor on MyClass, the C# compiler will helpfully provide one, for me. That’s not what I want, in this case, because, in that case, the class effectively becomes this:

public sealed class MyClass : SingletonBase<MyClass>
{
   public MyClass() {}
}

And, in that case, C# allows me to create instances until the cows come home:

var obj1 = new MyClass();
var obj2 = new MyClass();

...

var objN = new MyClass();

// All this compiles and works just fine!

Clearly, that isn’t what we want. But, the way C# works, the only way to prevent that is to add a private ctor to the MyClass type. So, my point is, remember that private ctor – it’s important!

Some things this class doesn’t do very well are: (A) support multiple constructors, (B) or constructors with parameters. In that case, you’ll probably want to override the Instance method and pass in parameters there. Remember, the private ctor isn’t going to be visible to callers, so there won’t be any way to pass parameters directly.

This class is part of the CG.Core NUGET package. The source can be found HERE. The package itself can be found HERE.

Thanks for reading!

Photo by Gary Ellis on Unsplash