Design Patterns – Singleton

By | 21/10/2020

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.



Leave a Reply

Your email address will not be published.