Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a generic singleton base class C# [duplicate]

I am trying to create a generic singleton base class like

public class SingletonBase<T> where T : class, new()
{
    private static object lockingObject = new object();
    private static T singleTonObject;
    protected SingletonBase()
    {

    }

    public static T Instance
    {
        get
        {
            return InstanceCreation();
        }
    }
    public static T InstanceCreation()
    {
        if(singleTonObject == null)
        {
             lock (lockingObject)
             {
                  if(singleTonObject == null)
                  {
                       singleTonObject = new T();
                  }
             }
        }
        return singleTonObject;
    }
}

But I have to make constructor as public in derived one.

public class Test : SingletonBase<Test>
{
    public void A()
    {

    }
    private Test()
        : base()
    { }
}

Compilation Error:

'Test' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Test'

How can I achieve this?

like image 589
D J Avatar asked Mar 25 '13 04:03

D J


2 Answers

The problem is your generic constraint where T : class, new(). The new() constraint requires a public, parameterless constructor on T. There is no way around this; you need to provide such a constructor in Permission Controller.

like image 152
Jason Watkins Avatar answered Sep 30 '22 12:09

Jason Watkins


I would avoid this kind of recursive generic pattern. Read this this blog post for a detailed explanation of the pattern and reasons not to use it.

As far as I can tell, you don't need to have any sub-classes of SingletonBase<T>. I can't see anything that a subclass of SingletonBase<T> would be able to add to your code. I would simply rewrite it as

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

You can then use it as

var test = Singleton<Test>.Instance;

If you want to be able to use Test as a singleton, create it as

public class Test 
{
    public static T Instance
    {
        get { return Singleton.Instance<Test>; }
    }
}
like image 40
p.s.w.g Avatar answered Sep 30 '22 11:09

p.s.w.g