From Wikipedia:
“In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one ‘single’ instance. This is useful when exactly one object is needed to coordinate actions across the system. The term comes from the mathematical concept of a singleton.“
In this post, we will see how to implement this pattern in a .NET Console application.
We start creating a Console application where we will define an interface called ICore:
[ICORE.CS]
namespace Singleton
{
public interface ICore
{
int Multiplication(int val);
int GetCoxValue();
}
}
Now, we create a class called Core where we will implement the ICore interface:
[CORE.CS]
using System;
namespace Singleton
{
public class Core : ICore
{
// Definition of a variable used in Multiplication method
private readonly int cox;
public Core()
{
// Initialization of cox
cox = DateTime.Now.Second;
}
public int Multiplication(int val)
{
return val * cox;
}
public int GetCoxValue()
{
return cox;
}
}
}
Finally, we modify the file Program.cs in order to use the class Core:
[PROGRAM.CS]
using System;
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start test without Singleton");
TestWithoutSingleton();
}
static void TestWithoutSingleton()
{
CallMultiplicationCore("Test 1");
Console.WriteLine();
System.Threading.Thread.Sleep(1000);
CallMultiplicationCore("Test 2");
Console.WriteLine();
System.Threading.Thread.Sleep(2000);
CallMultiplicationCore("Test 3");
}
static void CallMultiplicationCore(string title)
{
var objCore = new Core();
Console.WriteLine(title);
Console.WriteLine("Input 3");
Console.WriteLine($"Cox value: {objCore.GetCoxValue()}");
Console.WriteLine($"Result: {objCore.Multiplication(3)}");
}
}
}
If we run the application, this will be the result:
In this case the value of Cox is everytime different because, when the application runs CallMultiplicationCore, it creates a new instance of the Core class.
Now, we create a new class called Core2 where we will implement the Singleton pattern:
[CORE2.CS]
using System;
namespace Singleton
{
public sealed class Core2 : ICore
{
// Definition of a variable used in Multiplication method
private readonly int cox;
// We hide our constructor from the consumer classes by making it private
private Core2()
{
// Initialization of cox
cox = DateTime.Now.Second;
}
public int Multiplication(int val)
{
return val * cox;
}
public int GetCoxValue()
{
return cox;
}
// We load the class in a lazy way so the instance is going to be created
// only when it is actually needed
private static Lazy<Core2> newCore2 = new Lazy<Core2>(() => new Core2());
// We will use the CreateInstance property in order to instance our class
// and it will be instantiated only once and shared for every other call.
public static Core2 CreateInstance => newCore2.Value;
}
}
Finally, we modify the file Program.cs in order to use the class Core2:
[PROGRAM.CS]
using System;
namespace Singleton
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start test without Singleton");
TestWithoutSingleton();
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Start test with Singleton");
TestWithSingleton();
}
static void TestWithoutSingleton()
{
CallMultiplicationCore("Test 1");
Console.WriteLine();
System.Threading.Thread.Sleep(1000);
CallMultiplicationCore("Test 2");
Console.WriteLine();
System.Threading.Thread.Sleep(2000);
CallMultiplicationCore("Test 3");
}
static void CallMultiplicationCore(string title)
{
var objCore = new Core();
Console.WriteLine(title);
Console.WriteLine("Input 3");
Console.WriteLine($"Cox value: {objCore.GetCoxValue()}");
Console.WriteLine($"Result: {objCore.Multiplication(3)}");
}
static void TestWithSingleton()
{
CallMultiplicationCore2("Test 1");
Console.WriteLine();
System.Threading.Thread.Sleep(1000);
CallMultiplicationCore2("Test 2");
Console.WriteLine();
System.Threading.Thread.Sleep(2000);
CallMultiplicationCore2("Test 3");
}
static void CallMultiplicationCore2(string title)
{
var objCore2 = Core2.CreateInstance;
Console.WriteLine(title);
Console.WriteLine("Input 3");
Console.WriteLine($"Cox value: {objCore2.GetCoxValue()}");
Console.WriteLine($"Result: {objCore2.Multiplication(3)}");
}
}
}
Now, if we run the application, this will be the result:
We can see that, using Singleton pattern, the value of Cox is always 57 because there is only one instance of Core2.