What is the Singleton Pattern?
The Singleton Design Pattern is a creational pattern that ensures only one instance of a class is created and provides a global access point to that instance.
In simple terms, imagine you have a class that should only ever have one object (like a single log manager, configuration handler, or shared resource). The Singleton pattern helps you do exactly that.
When to Use Singleton Pattern?
Use Singleton when,
	- You need to limit a class to a single instance.
- You want to control access to shared resources like file handlers, database connections, logging services, etc.
- You want a centralized object that's reused throughout the application.
Basic Structure of Singleton Pattern
Key Points
	- Private constructor to prevent external instantiation.
- Static variable to hold the single instance.
- Public static method or property to provide access.
Basic Example
public sealed class Singleton
{
    private static Singleton instance = null;
    // Private constructor to prevent object creation
    private Singleton()
    {
        Console.WriteLine("Singleton instance created");
    }
    // Public method to get the instance
    public static Singleton GetInstance()
    {
        if (instance == null)
        {
            instance = new Singleton();
        }
        return instance;
    }
}
Thread-Safe Singleton
In multi-threaded applications, the basic version might create multiple instances. So we make it thread-safe:
Using Lock
public sealed class Singleton
{
    private static Singleton instance = null;
    private static readonly object lockObj = new object();
    private Singleton() { }
    public static Singleton GetInstance()
    {
        lock (lockObj)
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
        }
        return instance;
    }
}
Best Practice: Lazy Initialization
C# also provides an easy way using Lazy<T>.
public sealed class Singleton
{
    private static readonly Lazy<Singleton> instance = 
        new Lazy<Singleton>(() => new Singleton());
    private Singleton() { }
    public static Singleton Instance => instance.Value;
}
Eager vs Lazy Loading
 
	
		
			| Approach | Description | 
		
			| Eager | The instance is created at application start. Good for performance-critical cases. | 
		
			| Lazy | The instance is created when it's needed. Saves memory and start-up time. | 
	
Drawbacks of Singleton
	- Can make unit testing difficult (tight coupling).
- It might be overused when a simple static class would do.
- Risk of hidden dependencies across the app.
Real-Time Use Cases
	- Logger
- Configuration settings
- Database connection manager
- Caching mechanism
Summary
	- Singleton ensures one instance only.
- It’s helpful for managing shared resources.
- Make it thread-safe for multi-threaded apps.
- Use lazy loading for better performance when n