Are you joking “It compiles, ship it!”? You might actually be doing just that…

A while back, I talked with someone about using the Singleton Design Pattern vs. using an IoC container and registering your class as singleton.

Response:

IoC containers are regularly bootstrapped wrongly, resulting in your product not working as it should. And you don’t discover that until you startup the product. I’d rather use the Singleton Pattern. That way, the compiler will protect against errors.

Ahem… Counter example:


public class Singleton 
{
    private static Singleton instance = new Singleton();

    public static Singleton Instance => return new Singleton();
}

It compiles, right? Look again. Woops… Instance is creating a new instance every time! (Think this is too simplistic? Realize that there can be huge code clutter in such a class, effectively obscuring this from view.)

A test would quickly expose the mistake:


public void Instance_ShouldReturnSameInstanceEveryTime
{
    // Arrange
    Singleton singleton = Singleton.Instance;

    // Act
    Singleton result = Singleton.Instance;

    // Assert
    Assert.AreSame(singleton, result);
}

Doing this, means that with regards to the question “Is it really a Singleton?”, the test answers it. From that perspective, it doesn’t really matter whether you use an IoC container or a Singleton Design Pattern. What matters instead, is whether you wrote tests and whether your Singleton class has an interface so that you can mock it. The Singleton pattern is usually employed somewhat like this:


public class Something
{
    public void DoSomething()
    {
        ...
        Singleton.Instance.DoSomething();
        ...
    }
}

An IoC container wouldn’t change much:


public class Something
{
    public void DoSomething()
    {
        ...
        Container.GetInstance<Singleton>().DoSomething();
        ...
    }
}

However, if you were to switch to Dependency Injection in combination with IoC, introducing interface ISingleton in the process, you can use mocks to replace an actual instance of Singleton in your tests, yielding decoupling and clarity of dependencies, potential speed-up of tests and a way to assert that expected calls to ISingleton are actually made.

The test coverage is good and all tests pass. Ship it!

Leave a Reply

Your email address will not be published. Required fields are marked *