13

I have a question, is this the correct approach to make a Generic Singleton?

 public class Singleton<T> where T : class, new()
    {
        private static T instance = null;

        private Singleton() { }

        public static T Instancia
        {
            get 
            {
                if (instance == null)
                    instance = new T();
                return instance;
            }
        }
    }

EDIT:

Checking some PDFs I found a generic Singleton made this other way, is this other correct?

public class Singleton<T> where T : class, new()
{
    Singleton() { }

    class SingletonCreator
    {
        static SingletonCreator() { }
        // Private object instantiated with private constructor
        internal static readonly T instance = new T();
    }

    public static T UniqueInstance
    {
        get { return SingletonCreator.instance; }
    }
}
Machavity
  • 30,841
  • 27
  • 92
  • 100
MRFerocius
  • 5,509
  • 7
  • 39
  • 47
  • If your purpose with this is to implement a sort of Service Locator, then don't: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx – Mark Seemann Feb 23 '10 at 15:13
  • you cannot new up a singleton. that is the point. and the reason your generic singleton implementations are not. singletons. – Sky Sanders Feb 23 '10 at 15:34

9 Answers9

28

The problem with a generic singleton factory is that since it is generic you do not control the "singleton" type that is instantiated so you can never guarantee that the instance you create will be the only instance in the application.

If a user can provide a type to as a generic type argument then they can also create instances of that type. In other words, you cannot create a generic singleton factory - it undermines the pattern itself.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
  • Could the type be saved in a static array, though? – Franz Feb 23 '10 at 15:03
  • @Franz - I am not sure what you mean - could you ask your question in a different way? – Andrew Hare Feb 23 '10 at 15:04
  • Well you can make the constructors protected and make the template class a friend. Then only the Singleton-class can make instances. Oops, I do not know if friends exists in C#, was thinking of C++. – monoceres Feb 23 '10 at 15:04
  • Is is true that the type to be made a singleton could have an internal constructor but that would only guarantee that the type was a singleton *outside the current assembly*. You cannot create a true singleton this way as other types in the same assembly could create instances of the singleton type just as easily. – Andrew Hare Feb 23 '10 at 15:08
  • Andrew thank you very much for your reply. Is the second version accurate? Do you find any problem with that, I took it from Judith Bishop´s Design Patterns in C# book. – MRFerocius Feb 23 '10 at 15:22
  • While you can't restrict how many times Singleton is used, it is certainly still going to work as a base implementation to allow singletons of various differing types. I don't think this answer necessarily considers all use-cases. For example, Singleton will be a valid singleton type. – Jeff Yates Feb 23 '10 at 15:22
  • Andrew, what I meant is having an static array of types that have already been instantiated in the generic class, which is then checked against the type of the current class. I don't know whether this is possible in C# though, since I come more from a scripting-language background, where this would be easily possible (PHP, y'know?) – Franz Feb 23 '10 at 15:24
  • if you declare the class the generic singleton is going to use as internal, no one can misuse your class because they can't instantiate it. – Nathan Tregillus Jul 26 '17 at 15:10
12

this is my point using .NET 4

public class Singleton<T> where T : class, new()
    {
        private Singleton (){}

        private static readonly Lazy<T> instance = new Lazy<T>(()=> new T());

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

Usage pattern:

var journalSingleton = Singleton<JournalClass>.Instance;
Alexandr
  • 1,452
  • 2
  • 20
  • 42
2

Here is my implementation using a non-public constructor. The only issue right now is there is no way to have a custom constraint on C# generics, so I have to throw a run-time exception for derived classes with public default constructors instead of a compile-time error.

using System;
using System.Reflection;
using System.Threading;

/// <summary>
/// A generic abstract implementation of the Singleton design pattern (http://en.wikipedia.org/wiki/Singleton_pattern).
/// 
/// Derived type must contain a non-public default constructor to satisfy the rules of the Singleton Pattern.
/// If no matching constructor is found, an exception will be thrown at run-time. I am working on a StyleCop
/// constraint that will throw a compile-time error in the future.
/// 
/// Example Usage (C#):
/// 
///     class MySingleton : Singleton&lt;MySingleton&gt;
///     {
///         private const string HelloWorldMessage = "Hello World - from MySingleton";
///     
///         public string HelloWorld { get; private set; }
///
///         // Note: *** Private Constructor ***
///         private MySingleton()
///         {
///             // Set default message here.
///             HelloWorld = HelloWorldMessage;
///         }
///     }
/// 
///     class Program
///     {
///         static void Main()
///         {
///             var mySingleton = MySingleton.Instance;
///             Console.WriteLine(mySingleton.HelloWorld);
///             Console.ReadKey();
///         }
///     }
/// </summary>
/// <typeparam name="T">Type of derived Singleton object (i.e. class MySingletone: Singleton&lt;MySingleton&gt;).</typeparam>
public abstract class Singleton<T> where T : class
{
    /// <summary>
    /// "_instance" is the meat of the Singleton<T> base-class, as it both holds the instance
    /// pointer and the reflection based factory class used by Lazy&lt;T&gt; for instantiation.
    /// 
    /// Lazy&lt;T&gt;.ctor(Func&lt;T&gt; valueFactory,LazyThreadSafetyMode mode), valueFactory:
    /// 
    ///     Due to the fact Lazy&lt;T&gt; cannot access a singleton's (non-public) default constructor and
    ///     there is no "non-public default constructor required" constraint available for C# 
    ///     generic types, Lazy&lt;T&gt;'s valueFactory Lambda uses reflection to create the instance.
    ///
    /// Lazy&lt;T&gt;.ctor(Func&lt;T&gt; valueFactory,LazyThreadSafetyMode mode), mode:
    /// 
    ///     Explanation of selected mode (ExecutionAndPublication) is from MSDN.
    ///     
    ///     Locks are used to ensure that only a single thread can initialize a Lazy&lt;T&gt; instance 
    ///     in a thread-safe manner. If the initialization method (or the default constructor, if 
    ///     there is no initialization method) uses locks internally, deadlocks can occur. If you 
    ///     use a Lazy&lt;T&gt; constructor that specifies an initialization method (valueFactory parameter),
    ///     and if that initialization method throws an exception (or fails to handle an exception) the 
    ///     first time you call the Lazy&lt;T&gt;.Value property, then the exception is cached and thrown
    ///     again on subsequent calls to the Lazy&lt;T&gt;.Value property. If you use a Lazy&lt;T&gt; 
    ///     constructor that does not specify an initialization method, exceptions that are thrown by
    ///     the default constructor for T are not cached. In that case, a subsequent call to the 
    ///     Lazy&lt;T&gt;.Value property might successfully initialize the Lazy&lt;T&gt; instance. If the
    ///     initialization method recursively accesses the Value property of the Lazy&lt;T&gt; instance,
    ///     an InvalidOperationException is thrown.
    /// 
    /// </summary>
    private static readonly Lazy<T> _instance = new Lazy<T>(() =>
                                                                {
                                                                    // Get non-public constructors for T.
                                                                    var ctors = typeof (T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);

                                                                    // If we can't find the right type of construcor, throw an exception.
                                                                    if (!Array.Exists(ctors, (ci) => ci.GetParameters().Length == 0))
                                                                    {
                                                                        throw new ConstructorNotFoundException("Non-public ctor() note found.");
                                                                    }

                                                                    // Get reference to default non-public constructor.
                                                                    var ctor = Array.Find(ctors, (ci) => ci.GetParameters().Length == 0);

                                                                    // Invoke constructor and return resulting object.
                                                                    return ctor.Invoke(new object[] {}) as T;
                                                                }, LazyThreadSafetyMode.ExecutionAndPublication);

    /// <summary>
    /// Singleton instance access property.
    /// </summary>
    public static T Instance
    {
        get { return _instance.Value; }
    }
}

/// <summary>
/// Exception thrown by Singleton&lt;T&gt; when derived type does not contain a non-public default constructor.
/// </summary>
public class ConstructorNotFoundException : Exception
{
    private const string ConstructorNotFoundMessage = "Singleton<T> derived types require a non-public default constructor.";
    public ConstructorNotFoundException() : base(ConstructorNotFoundMessage) { }
    public ConstructorNotFoundException(string auxMessage) : base(String.Format("{0} - {1}", ConstructorNotFoundMessage, auxMessage)) { }
    public ConstructorNotFoundException(string auxMessage, Exception inner) : base(String.Format("{0} - {1}", ConstructorNotFoundMessage, auxMessage), inner) { }
}
1

You can make a singleton base class using a bit of cheating (reflection). You can (run-time) enforce a class has no public constructor.

public abstract class Singleton<T> where T : Singleton<T> {
    private const string ErrorMessage = " must have a parameterless constructor and all constructors have to be NonPublic.";
    private static T instance = null;
    public static T Instance => instance ?? (instance = Create());

    protected Singleton() {
        //check for public constructors
        var pconstr = typeof(T).GetConstructors(BindingFlags.Public | BindingFlags.Instance);
        //tell programmer to fix his stuff
        if (pconstr.Any())
            throw new Exception(typeof(T) + ErrorMessage);
    }

    private static T Create() {
        try {
            //get nonpublic constructors
            var constructors = typeof(T).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
            //make sure there is but 1 and use that
            return (T)constructors.Single().Invoke(null);
        }
        catch {
            //tell programmer to fix his stuff
            throw new Exception(typeof(T)+ErrorMessage);
        }
    }
}
Wesley
  • 61
  • 5
0

For a generic piece of code that will be reused, you should consider thread safety at the point where you create the singleton instance.

As it is, (instance == null) could evaluate to true on separate threads.

xyz
  • 27,223
  • 29
  • 105
  • 125
  • Good point, though realistically, there are many constructs which are not thread safe, including most collections which we use on a daily basis. – Nick Feb 23 '10 at 15:28
  • @Nick: Advocating bad behaviour because there exists bad behaviour is very very poor. – Jeff Yates Feb 23 '10 at 15:31
  • 1
    @Jeff - I don't think it's advocating bad behavior at all. Most applications don't need to be thread safe, so it's not always worth the cycles to ensure that it is without that requirement. It's subjective. Saying that a solution is bad because it doesn't account for a use that most people won't have isn't necessarily valid. – Nick Feb 23 '10 at 15:43
  • @Nick "not worth the cycles" sounds like premature optimisation to me. When thread safety is as easy to add as it is in this case, a small piece of generic code, why not? – xyz Feb 23 '10 at 15:53
  • @Nick: I was commenting more on the philosophy that existing bad behaviour allows others to repeat behaviour than the advice for this particular question. – Jeff Yates Feb 23 '10 at 18:34
  • @Jeff - I understand, but it also implies that non-thread safe collections are a bad behavior, since that is what I mentioned specifically, and I really don't think they are. But as we've seen, it brings up all sorts of others with premature optimization and over architecture, etc. – Nick Feb 23 '10 at 18:38
0

for creating generic Singleton factory you can use something like this class as your factory :

public abstract class BaseLazySingleton<T> where T : class
    {
        private static readonly Lazy<T> LazyInstance =
            new Lazy<T>(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
    }

Note that

  1. this generator is abstract so no one can create new Instance of this class.
  2. constructor method is protected Not public
0

This how I did it, using the Current pattern (also thread safe initialization)

public static class Singleton<T> 
{
    private static readonly object Sync = new object();

    public static T GetSingleton(ref T singletonMember, Func<T> initializer)
    {
        if (singletonMember == null)
        {
            lock (Sync)
            {
                if (singletonMember == null)
                    singletonMember = initializer();
            }
        }
        return singletonMember;
    }
}

Usage:

private static MyType _current;
public static MyType Current = Singleton<MyType>.GetSingleton(ref _current, () => new MyType());

Consume the singleton:

MyType.Current. ...
MaurGi
  • 1,698
  • 2
  • 18
  • 28
0

It is possible without reflection.

We just need a generic class for the singleton pattern which takes two parameter - the implementation of the concrete singleton class and the interface for the concrete singleton. The generic singleton class implements the singleton pattern and all the stuff you need - for example logging, locks or what else.

using System;
using System.Diagnostics;

namespace Singleton
{
    class Program
    {
        static void Main(string[] args)
        {
            Something.Instance.SayHello();
        }
    }

    /// <summary>
    /// Generic singleton pattern implementation
    /// </summary>
    public class SingletonImplementation<Implementation, ImplementationInterface>
           where Implementation : class, ImplementationInterface, new()
    {
        private SingletonImplementation() { }

        private static Implementation instance = null;
        public static ImplementationInterface Instance
        {
            get
            {
                // here you can add your singleton stuff, which you don't like to write all the time

                if ( instance == null )
                {
                    instance = new Implementation();
                }

                return instance;
            }
        }
    }

    /// <summary>
    /// Interface for the concrete singleton
    /// </summary>
    public interface ISomething
    {
        void SayHello();
    }

    /// <summary>
    /// Singleton "held" or "wrapper" which provides the instance of the concrete singleton
    /// </summary>
    public static class Something
    {
        // No need to define the ctor private, coz you can't do anything wrong or useful with an instance of Something
        // private Implementation();

        /// <summary>
        /// Like common: the static instance to access the concrete singleton
        /// </summary>
        public static ISomething Instance => SingletonImplementation<ImplementationOfSomething, ISomething>.Instance;

        /// <summary>
        /// Concrete singleton implementation
        /// </summary>
        private class ImplementationOfSomething : ISomething
        {
            // No need to define the ctor private, coz the class is private.
            // private Implementation();

            public void SayHello()
            {
                Debug.WriteLine("Hello world.");
            }
        }
    }
}
Monotomy
  • 554
  • 1
  • 6
  • 24
-1

This is an example in Cpp but you can transform it to any other language:

template < class T> 
class singleton
{
private:
    static T* _instance;

public:
    static T* CreateInstance()
    {
        if (_instance == 0)  _instance = new T;
        return _instance;


    }
    static void Release()
    {

        if (_instance)
        {
            delete _instance;
            _instance = 0;

        }
    }
};

template<class T> T* singleton<T>::_instance = 0;
OpacANEBDOUR
  • 89
  • 1
  • 7
  • 2
    But the question is about c# – Pavel Anikhouski Dec 25 '19 at 10:42
  • 1
    Yes, it doesn't depend on any object oriented programming language, you can apply it to anyone you want it's just syntax that changed. Thanks – OpacANEBDOUR Dec 26 '19 at 12:05
  • 1
    @OpacANEBDOUR C# generics aren't even remotely comparable to C++ templates, at least not implementation-wise. Especially for a singleton class, language semantics would matter the most. Besides, again a non-thread-safe implementation. – Alexander Gräf Sep 14 '21 at 19:50