What is Singleton Design Pattern made Easy

In this simple guide, let's understand what is a singleton design pattern and how we can create and manage singletons with examples via IoC containers.

Introduction

A Singleton is one of the twenty three design patterns compiled to solve specific design problems which occur recursively across the software development. The Singleton pattern is a creational pattern which deals with how to create a class instance so that it is restricted to be created only once in its entire lifecycle and only one instance is to be used across the system in the entire flow.

Benefits of using a Singleton

Applying a Singleton pattern restricts the instantiation of a class to only one instance. This is one of the most simplest patterns which needs to be used carefully and only in required scenarios. When used unnecessarily, singleton patterns can create additional problems and can complicate the system flow which we call as an “anti-pattern” behavior.

How to create a Singleton?

A Singleton class can be simply created in three steps:

  1. Hide the constructor of the class by marking it private.
  2. Define a private static variable of the class to be made singleton and store an instance of the class to return.
  3. Define a public static method which can return the persisted instance of the class (stored in the private static field) when invoked.

For example in C# we can mark a class which offers some functionality as a singleton based on our requirement by following the above steps.

Creating and using Singleton with an Example in C#

Let’s take the example of a Http utility class that offers a http get functionality for a given URL and headers.

namespace netcore3app.Providers
{
    public class Http
    {
        private HttpClient client = new HttpClient();

        public async Task<HttpResponseMessage> GetHttp(
                     string url, Dictionary<string, string> headers)
        {

            var request = new HttpRequestMessage(HttpMethod.Get, url);

           foreach (var header in headers)
           {
            request.Headers.TryAddWithoutValidation(header.Key, header.Value);
            }

            return await client.SendAsync(request);
        }
    }
}

Now we don’t desire the utility class to be instantiated every time we require (since it’s costly to have multiple instances of HttpClient be created). We instead look to convert this class into a Singleton so that only one instance of the utility and thereby HttpClient be rotated across the system for all Http operations.

For that we mark the class as sealed (to prevent any inheritance by extension) and have a private static field that holds an instance of itself.

namespace netcore3app.Providers.Singletons
{
    // a singleton class
    public sealed class Http
    {
        private static HttpClient client = new HttpClient();

        // the single instance
        // which is always returned
        private static Http instance = null;

        // some functionality
        public async Task<HttpResponseMessage> GetHttp(
                  string url, Dictionary<string, string> headers)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, url);
 
            foreach (var header in headers)
            {
             request.Headers.TryAddWithoutValidation(header.Key, header.Value);
            }

            return await client.SendAsync(request);
        }
 
       // a private constructor
        private Http()
        {
        }

        // the method that returns an instance
        public static Http GetInstance()
        {
            if (instance == null)
            {
                instance = new Http();
            }
            return instance;
        }
    }
}

We then have the constructor marked private to restrict instantiation and add a new method GetInstance() that returns the instance of itself when invoked.

The method further delays instantiation of the class till the point of invocation and thereby creating a Lazy Initialization effect.


What is the difference between a Static Constructor and a Singleton?

  1. Static constructors are run once for a type at an unknown time before any of the static members are called.
  2. Adding a static constructor doesn’t stop the class from being initialized, it is just that the members which are desired to be instantiated only once are placed inside a static constructor (for example a HttpClient)
  3. A Singleton class has a private constructor by design, which stops it from being instantiated and hence only a single instance of the type can be circulated at any time.

Implementing Singleton using a Static Class

Another implementation can be having a static class which manages the Http utility object for us.

namespace netcore3app.Providers.Singletons
{
    // a static class is singleton by nature
    public static class HttpSingleton
    {
        // a private field to hold the instance of the type
        private static readonly Http instance = new Http();

        // a public property that returns the created instance
        public static Http Instance => instance;
    }
}

What are the differences between a Static class and a Singleton?

Singleton ClassStatic Class
can be instantiated, but only oncecan’t be instantiated at all
can support inheritance by implementing an interface. We can create many implementations during runtime if needed.can not implement an interface
singleton classes can be injected via constructorsstatic classes can’t
we can know exactly when the class is instantiatedwe don’t have the control over the object
singleton classes are not sticky – they can be designed to be loosely coupledstatic classes are sticky – they create a coupling when used inside a class
You can actually modify a value inside a singleton by providing a setter method for that fieldstatic classes can’t be changed, if we need to change some value inside a static class we need to restart the server
differences between a static class and a singleton

How to create Singleton with an IoC Containers – ASP.NET Core

In the modern day programming frameworks which heavily utilize the features of IoC Container frameworks such as Autofac or Ninject, marking a class as a Singleton has become easy and simplified, with the frameworks doing the heavy lifting for us. And in newer ASP framework aka the ASP.NET Core brings this feature built-in with its own container for instantiations, and so these approaches are not so required when using these frameworks.

For example, in ASP.NET Core which uses its built-in IoC container for object management, we can mark a class as a Singleton as below. This ensures that the container creates only a single object during the entire application lifetime and reuses the same object for all requesting clients.

services.AddSingleton<Http>();

This way we can create Singletons which can help reduce the number of instances created and contribute to the overall system’s performance (considerably).


Buy Me A Coffee

Found this article helpful? Please consider supporting!

Ram
Ram

I'm a full-stack developer and a software enthusiast who likes to play around with cloud and tech stack out of curiosity. You can connect with me on Medium, Twitter or LinkedIn.

Leave a Reply

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