Singletons and inheritance

For a long time, when people have asked about having inheritance and singletons, I’ve stated flatly that a singleton can’t be derived from. It stops being a singleton at that point. Even if the class is internal and you can prove that no other classes in the assembly do derive from the singleton and break the pattern’s effect, it’s still not a genuine singleton.

It was only when I was thinking about one of the comments about my enhanced enums proposal that I realised there’s an alternative approach. You can derive from a singleton as nested types of the Singleton itself and still keep the private constructor. That means that the singleton nature is still contained within the body of the text which declares the singleton class, even though that text actually declares more classes. Indeed, the singleton itself can even be abstract. Here’s an example:

using System;

public abstract class DataProvider
{
    static DataProvider instance = CreateDataProvider();
    
    public static DataProvider Instance
    {
        get { return instance; }
    }
    
    // Note that nested classes can call private members
    private DataProvider() {}

    public abstract void Connect();
    
    static DataProvider CreateDataProvider()
    {
        // Use Oracle on a Sunday, SQL Server otherwise
        if (DateTime.Now.DayOfWeek==DayOfWeek.Sunday)
        {
            return new OracleProvider();
        }
        else
        {
            return new SqlServerProvider();
        }
    }
    
    // Note that there’s no need to make the constructors
    // for the nested types non-public, as the classes
    // themselves are private to DataProvider.
    
    class OracleProvider : DataProvider
    {
        public override void Connect()
        {
            Console.WriteLine (“Connecting to Oracle”);
        }
    }

    class SqlServerProvider : DataProvider
    {
        public override void Connect()
        {
            Console.WriteLine (“Connecting to SQL Server”);
        }
    }
}

I’m not suggesting you should actually use a singleton for a data provider like this –
it just seemed like a simple example to demonstrate the point.

It is easy to validate that the singleton only allows one instance of DataProvider
to ever be constructed. (This version isn’t fully lazy, but that could be added if desired.)

It looks like I’ll have to revise my statement about inheritance from now on…

13 thoughts on “Singletons and inheritance”

  1. John:

    We use a pattern very similar to the one that you described to create a factory.

    Basically, we have a factory that is responsible for handing out several related types of object instances (or even other factories).

    There should only ever be one of these factories in memory at any given time (singleton), but the type of the factory can change based on platform (e.g. win/web).

    Like

  2. It’s not a singleton.

    1) You can create a new Oracle()
    2) There’s nothing to stop other classes from deriving from DataProvider
    3) You need to know which type of DataProvider to use when you make the call. (The point of my pattern above is that you don’t need to know what you’re going to use.)

    Like

  3. Hello Jon. I can see a little thing going wrong with this pattern: the DataProvider class is open for anyone to derive from it. I believe you should add a private constructor to it as you mentioned in the text.

    Like

  4. Hello Jon
    i wrote a class that i wished to be Generic Singleton like this :
    public abstract class BaseLazySingleton where T : class
    {
    private static readonly Lazy LazyInstance =
    new Lazy(CreateInstanceOfT, LazyThreadSafetyMode.ExecutionAndPublication);

        #region Properties
        public static T Instance
        {
            get { return LazyInstance.Value; }
        }
        #endregion
    
        #region Methods
        private static T CreateInstanceOfT()
        {
            return Activator.CreateInstance(typeof(T), true) as T;
        }
    
        protected BaseLazySingleton()
        {
        }
    
        #endregion
    }
    

    i would appreciate if you tell me your idea about this class. is this class realy GenericSingleton ?
    Thanks alot

    Like

  5. Hi Jon!
    i wrote a class that i wished to be Generic Singleton like this :
    public abstract class BaseLazySingleton where T : class
    {
    private static readonly Lazy LazyInstance =
    new Lazy(CreateInstanceOfT, LazyThreadSafetyMode.ExecutionAndPublication);

        #region Properties
        public static T Instance
        {
            get { return LazyInstance.Value; }
        }
        #endregion
    
        #region Methods
        private static T CreateInstanceOfT()
        {
            return Activator.CreateInstance(typeof(T), true) as T;
        }
    
        protected BaseLazySingleton()
        {
        }
    
        #endregion
    }
    

    i would appreciate if you tell me your idea about this class. is this class really Generic Singleton ?
    Thanks a lot!

    Like

    1. No, it’s not – it relies on being able to create an instance of T whenever it needs to, which means T doesn’t prevent anyone creating an instance of T multiple times, hence no singleton.

      Like

      1. thank you Jon for your replying
        please note to line 3 and 4 of my class ,where I wrote(ofCourse i think forget to add after Lazy ;) ) :
        private static readonly Lazy LazyInstance =
        new Lazy (CreateInstanceOfT, LazyThreadSafetyMode.ExecutionAndPublication);

        i read about this somewhere that it can guaranty threadSafe for us , isn’t it true?!!!
        I’m really confused by that . basically is it possible to create GenericSingleton or not ?

        thank you for spending time to answer my question

        Like

        1. Yes, it’s guaranteeing that this class doesn’t create more than one instance. But a singleton class guarantees that there’s only one instance of itself. You’ve got two classes here – BazeLazySingleton (which isn’t a singleton, as you can create multiple instances of it) and T, which isn’t a singleton because you’re calling Activator.CreateInstance, so it must be creatable externally as well. There’s no singleton here.

          Like

          1. really really really thanks and just one more little question :
            basically, is it possible to create GenericSingleton or not and if yes, then how ?(in my application,there is multiple kinds of settings that must be just one instance of them and i want to somehow reduce my code to create singleton design for them, but i dont know if it’s possible or not )
            thank you again!!!

            Like

            1. No, it’s not, in my view. (Or at least, you can have a generic singleton in some senses, but not in the way you’re thinking of.) I would personally suggest avoiding the singleton pattern entirely and using IoC for this – you would configure your app to only create a single instance, rather than making all the client code aware of it.

              Liked by 1 person

Leave a comment