Singleton pattern in parent class using C#

 Author: Shengtao Zhou       Created: 6/23/2019 2:14:38 AM       Modified: 6/24/2019 3:45:57 AM   More...
Here's an example for singleton pattern,
public sealed class Cache
{
    private static volatile Cache instance;
    private static object lockObject = new Object();
    private Cache() { }

    public static Cache CacheObject
    {
        get
        {
            if (instance == null)
            {
                lock (lockObject)
                {
                    if (instance == null)
                    {
                        instance = new Cache();
} } } return instance; } } }
To reuse a singleton class as parent class for a few singleton sub-classes you can't inherit from this class directly, since the result may not be what you want. Because  "instance" is a static variable, all the subclasses will share the same "instance" instead of one for each subclasses. The solution is create a generic parent class like this,

1. Create a generic parent class "CacheBase", the "instance" object will be created when the class is used for the first time. Since Singleton subclasses have private constructors, you have to use "Activator.CreateInstance" instead of "new T()" to initiate the subclasses.
    public abstract class CacheBase<T> where T : class
    {
        public string Value { get; set; }
        private static readonly Lazy<T> instance =
                        new Lazy<T>(() => Activator.CreateInstance(typeof(T), true) as T);

        public static T CacheObject { get { return instance.Value; } }

        public abstract void Run();
    }

2. Create class "CacheA" and "CacheB" inheriting from CacheBase and make constructors private.
    public sealed class CacheA: CacheBase<CacheA>
    {
        private CacheA() { }

        public override void Run()
        {
            //write your code for Run
        }
    }
    public sealed class CacheB : CacheBase<CacheB>
    {
        private CacheB() { }

        public override void Run()
        {
            //write your code for Run
        }
    }

3. Create a console application to test. 
    class Program
    {
        static void Main(string[] args)
        {
            CacheA a1 = CacheA.CacheObject;
            a1.Value = "Test CacheA";
            CacheB b1 = CacheB.CacheObject;
            b1.Value = "Test CacheB";
            CacheA a2 = CacheA.CacheObject;
            string valueA = a2.Value;
            Console.WriteLine("a2 value: " + valueA);
            CacheB b2 = CacheB.CacheObject;
            string valueB = b2.Value;
            Console.WriteLine("b2 value: " + valueB);
            Console.ReadKey();
        }
    }

Here is the result:

a2 value: Test CacheA
b2 value: Test CacheB

So it proves "CacheA.CacheObject" and "CacheB.CacheObject" only have one instance for each class.

For other "Gang of Four" design patterns, please reference Object Oriented Design Patterns Using C#.


More...          Back to List          

(Please enter you comments between 100 to 2000 characters. Thanks for your contribution.) 

         Created:       Modified: 

Editing a comment

       (Please enter you comments between 100 to 2000 characters. Please login before edit comment.)