Table of contents
1.
Introduction
2.
What is a Singleton Design Pattern in C#?
3.
Example of Singleton Design Pattern in C#
3.1.
Implementation in C#
3.2.
C#
3.3.
Output
4.
Application of Singleton Design Pattern
5.
Advantages of Singleton Design Pattern in C#
6.
Disadvantages of Singleton Design Pattern in C#
7.
Singleton Class vs. Static Methods
7.1.
Singleton Class:
7.2.
Static Methods:
8.
How to Implement Singleton Pattern in C# code
8.1.
No Thread Safe Singleton
8.2.
Thread-Safety Singleton
8.3.
Thread-Safety Singleton using Double-Check Locking
8.4.
Thread-safe Without a Lock
8.5.
Using .NET 4's Lazy<T> type
9.
Frequently Asked Questions
9.1.
Is Singleton design pattern thread-safe in C#?
9.2.
What design pattern is singleton?
9.3.
How to create an object in Singleton C#?
9.4.
What is the purpose of singleton?
9.5.
What are the real examples of singleton design pattern?
10.
Conclusion
Last Updated: Mar 27, 2024
Medium

Singleton Design Pattern in C#

Author Kanak Rana
1 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Do you ever wonder how can a single object be used to share a different part of the program? It is done by singleton design.

singleton design pattern c#

A Singleton Design Pattern in C# is a creational design pattern used to ensure that a class has only one instance. It provides global access for that instance for the entire application. In this article will learn all about Singleton Design Pattern in C# with examples, applications, advantages, disadvantages and implementation.

First things first, let us take a look at the definition of a Singleton Design Pattern. 

What is a Singleton Design Pattern in C#?

The Singleton design pattern is the best-known design pattern in C#. A class has only one instance in the code that provides a global point of access in this pattern. A singleton is addressed as a class that allows only one example of itself to be created and typically offers simple access to that instance.

singleton design pattern in c#

In C#, there are several ways to implement the singleton pattern. A singleton pattern shares the following characteristics.

In singleton sealed class is there. A sealed class means the class cannot be inherited by any class but can be instantiated.

Static variable stores a reference to the single instance created.

A public and static method to get the reference to the new entity created by instance. 

It has a private and parameterless single constructor. This is required because the class cannot be instantiated from outside the class. It only works from within the class.

Example of Singleton Design Pattern in C#

Implementation in C#

  • C#

C#

using System;
using System.Threading;
namespace Singleton
{
   class Singleton
   {
       private Singleton() {}
       private static Singleton _instance;
       private static readonly object _mutex = new object();
       public static Singleton GetInstance(string x)
       {
           if (_instance==null)
           {
               lock (_mutex)
               {
                   if (_instance== null)
                   {
                       _instance= new Singleton();
                       _instance.Value =x;
                   }
               }
           }
           return _instance;
       }
       public string Value { get; set; }
   }
   class Temp{
       static void Main(string[] args)
       {
  
           Thread freind1 = new Thread(() =>
           {
               TestSingleton("Coding");
           });
           Thread freind2 = new Thread(() =>
           {
               TestSingleton("ninjas");
           });
  
           freind1.Start();
           freind2.Start();
           freind1.Join();
           freind2.Join();
       }
  
       public static void TestSingleton(string x)
       {
           Singleton cp = Singleton.GetInstance(x);
           Console.WriteLine(cp.Value);
       }
   }
}

Output

Output

Explanation: The multithreading problem is solved by the above code solution using the lock. However, the issue is that it makes your program slower because only one thread can ever use the Get Instance property at once. With the help of the double-checked locking mechanism, we can solve the multiple input.

Real-world code in C#

C# is a versatile and powerful programming language that's widely used in various industries to create a diverse range of applications. Here are some practical examples of C# code that illustrate its real-world applications:

1. Web Development:

using System.Web.Http;

public class ProductsController : ApiController
{
    private readonly ProductRepository _repository;

    public ProductsController(ProductRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public IEnumerable<Product> GetProducts()
    {
        return _repository.GetAllProducts();
    }

    [HttpPost]
    public IHttpActionResult CreateProduct(Product product)
    {
        _repository.AddProduct(product);
        return Ok();
    }
}

 

This code demonstrates a simple web API controller that handles GET and POST requests to manage a list of products. It interacts with a data repository to retrieve and store product information, showcasing C#'s role in web development and API creation.
 

2. Desktop Applications:

using System.Windows.Forms;

public partial class MainWindow : Form
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void buttonCalculate_Click(object sender, EventArgs e)
    {
        double num1 = double.Parse(textBox1.Text);
        double num2 = double.Parse(textBox2.Text);
        double result = num1 + num2;
        labelResult.Text = result.ToString();
    }
}

 

This code creates a simple calculator application with a user interface for taking input and displaying results. It demonstrates C#'s capabilities in desktop application development, user interaction, and event-driven programming.

 

3. Game Development:

using Microsoft.Xna.Framework;

public class Player : GameObject
{
    public override void Update(GameTime gameTime)
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        Position += new Vector2(horizontal, vertical) * Speed * gameTime.ElapsedGameTime.TotalSeconds;
    }
}

 

This code snippet controls a player character's movement in a game, taking input from the keyboard and updating its position accordingly. It highlights C#'s use in game development, including input handling, object-oriented programming, and game logic.

Application of Singleton Design Pattern

Some real-time techniques in which the Singleton Design Pattern can be used:

Proxies for Services: Invoking a Service API is a complex operation in an application, as we all know. The most extended process is creating the Service client to invoke the service API. If you make the Service proxy as a Singleton, your application's performance will improve.

Facades: Database connections can also be created as Singletons, which improves application performance.

 Logs: Performing an I/O operation on a file in an application is an expensive operation. If you create your Logger as a Singleton, the I/O operation will perform better. A public and static method to get the reference to the new entity created by instance.

Data sharing: If you have any constant or configuration values, you can store them in Singleton so other application components can read them.

Caching: As we all know, retrieving data from a database takes time. You can avoid DB calls by caching your application's master and configuration in memory. In such cases, the Singleton class can handle caching efficiently with thread synchronization, significantly improving application performance.

Advantages of Singleton Design Pattern in C#

The following are the advantages-

Advantages of Singleton Design Pattern in C#
  • It supports lazy loaded and static initialization.
     
  • Interfaces can be implemented using the singleton pattern.
     
  • It helps in the hiding of dependencies.
     
  • It also provides a single access point to a particular example, making it simple to maintain.

Disadvantages of Singleton Design Pattern in C#

The following are the disadvantages -

Disadvantages of Singleton Design Pattern in C#
  • Unit testing is challenging because it introduces a global state into an application.
     
  • Locking reduces the chance of parallelism within a program.
     
  • Concurrency

Singleton Class vs. Static Methods

Here are the differences between Singleton Class and Static Methods:

Singleton Class:

  • A singleton class is a class that can only be instantiated once in an application.
     
  • It provides a single point of access to its instance.
     
  • The instance of the singleton class is typically accessed through a static property or method.
     
  • Singleton classes are useful for managing shared resources or for creating a centralized point of control in an application. 

Static Methods:

  • A static method is a method that belongs to a class rather than an instance of the class.
     
  • Static methods can be called without creating an instance of the class.
     
  • Static methods are often used for utility functions or for operations that do not require access to instance-level data.
     
  • Static methods are typically accessed through the class name rather than an instance of the class.
     

Singleton class is used when there should only be one instance of the class, while static methods are used when a method does not require an instance of the class to be created.

How to Implement Singleton Pattern in C# code

There are many ways to implement the Singleton Design Pattern in C#. Here we have provided some snippets so that one would understand them better.

  1. No Thread Safe Singleton
  2. Thread-Safety Singleton
  3. Thread-Safety Singleton using Double-Check Locking
  4. Thread-safe Without a Lock
  5. Using .NET 4's Lazy<T> type

No Thread Safe Singleton

public closed class NoThreadFirst {
     private NoThreadFirst() {
   
        }
     private static NoThreadFirst instances = null;
     public static NoThreadFirst Instances {
            get {
         if (instances == null)
                 {
                    instances = new NoThreadFirst();
                }
         return instances;
            }
        }
    }

Explanation: When two concurrent threads evaluate that the condition (if instance == null) is accurate, they both create instances of the class, violating the singleton framework pattern.

Thread-Safety Singleton

public closed class ThreadSafety
{
    private static ThreadSafety instances = null;
    protected static readonly firstObject codelock = new firstObject();

    ThreadSafety()
    {
    }

    public static ThreadSafety Instances
    {
        get
        {
    	 lock (codelock)
            {
        	 if (instances == null)
                {
                    instances = new ThreadSafety();
                }
        	 return instances;
            }
        }
    }
}

Explanation: This is a thread-safe version. Before generating an instance, a lock of an able-to-share entity is acquired, and a copy check is performed.

  • Because locking helps ensure that all read processes occur logically after the lock has been obtained on a specific item, having a lock reduces multiple threads from generating the same class object. Unlocking ensures that all writes occur logically before the lock is released.
     
  • Because only one thread can be in that section of code, the first thread will already create the instance; thus, the expression evaluates to false. Acquiring a lock each time an instance is requested has a poor performance impact.
     
  • This method, rather than locking on the type (Singleton), locks on the static value of a class variable.
     
  • A stalemate or deadlock may occur if you close an element other classes can obtain and lock on to.
     
  • As a general rule, class-specific objects should be kept out of the public eye. As a result, writing thread-safe programs has become much more manageable.

 

Thread-Safety Singleton using Double-Check Locking

public closed class ThreadSafetyUsingDoubleCheckLocking
{
   protected static ThreadSafetyUsingDoubleCheckLocking instances = null;

   protected static readonly firstObject codelock = new firstObject();

   ThreadSafetyUsingDoubleCheckLocking()
   {
   }
   public static ThreadSafetyUsingDoubleCheckLocking Instances
   {
       get
       {
    if (instances == null)
           {
        lock (codelock)

               {
            if (instances == null)
                   {
                       instances = new v();
                   }
               }
           }
    return instances;
       }
   }
}

Explanation: This approach is designed to be more thread-safe than previous iterations by not using locks.

Thread-safe Without a Lock

public closed class NoLockThreadSafe
{
   private static readonly NoLockThreadSafe instances = new NoLockThreadSafe();

   static NoLockThreadSafe()
   {
   }

   private NoLockThreadSafe()
   {
   }

   public static NoLockThreadSafe Instances

   {
       get
       {
    return instances;
       }
   }
}

Explanation: A new type of check must be performed regardless of what else is happening. Because it verifies for a newly created type, this check will be faster than the additional checking performed by its predecessor instances.

Using .NET 4's Lazy<T> type

public closed class LazyTypeNet4
{
   private static readonly Lazy<LazyTypeNet4> lazy =

   new Lazy<LazyTypeNet4>(() => new LazyTypeNet4())

   public static LazyTypeNet4 Instances { get { return lazy.Values; } }

   private LazyTypeNet4()
   {
   }
}

Explanation: It will be simple to use and trustable. You may also need to use the IsValueCreated property to assess whether or not the instance has been created.

The default thread-safety mode for the LazySingleton is LazyThreadSafetyMode.ExecutionAndPublication. You may want to experiment with different methods to see which ones work best.

Frequently Asked Questions

Is Singleton design pattern thread-safe in C#?

A singleton class does not provide any thread safety. Multiple threads are able to access singleton and create objects simultaneously. Thus violating the principles of the Singleton concept. Although Singleton is not thread-safe, different approaches for the implementation are made to make the Singleton thread-safe.

What design pattern is singleton?

  • Singleton pattern is a creational design pattern used to ensure that a class has only one instance. Or, in simpler words,
     
  • Singleton is a class that allows only a single instance of itself to be created and gives simple access to that instance.
     
  • Singleton pattern is easy to maintain as it provides a single point of access to an instance.

How to create an object in Singleton C#?

Firstly we have to make the class constructor private to prevent direct creation. Then we have to provide a static method within the class to create or access the single instance of the class. Then we have to use a private static field to store the instance. Then we have to check if the instance already exists in the static method.If it does, return the existing instance; if not, create a new one.

What is the purpose of singleton?

The purpose of SIngleton is to provide global access to instances. It allows control over object creation. In a Singleton, a class is defined in such a way that only one instance is created in the entire execution ofthe program. Also, Singleton classes are used for driver objects, thread pools and 4database connections.

What are the real examples of singleton design pattern?

There are many real-world examples of the Singleton pattern design. They include thread pools, and database connection pools, where it is used for distributing tasks in multithreaded applications. Caching systems and GUI components also make use of Singleton Design Patterns.

Conclusion

In this article, we have covered the Singleton Design Pattern in C#. We will look into the different ways to implement the Singleton Design Pattern in C#. 

Check out some related articles below.

Refer to our guided paths on Coding Ninjas Studio to learn more about DSA, Competitive Programming, JavaScript, System Design, etc. Enrol in our courses and refer to the mock test and problems available. Take a look at the interview experiences and interview bundle for placement preparations.

Happy Coding! 

Live masterclass