Skip to main content
added 50 characters in body; edited tags; edited title
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

How is the design of this Singleton implementation using generics

I did this as an exercise just to practivepractice/improve using generics.

New LockerObject 36aa2282-d745-43ca-84d2-998a78e39d51
Factory<T>::Create()
MyClass created
MyClassFactory::Create()
MyClass created
Singleton<T>::ValueMyClass is already created
Singleton<T, F>::ValueMyClass is already created
New LockerObject 36aa2282-d745-43ca-84d2-998a78e39d51
Factory<T>::Create()
MyClass created
MyClassFactory::Create()
MyClass created
Singleton<T>::ValueMyClass is already created
Singleton<T, F>::ValueMyClass is already created

How is the design of this Singleton implementation

I did this as an exercise just to practive/improve using generics.

New LockerObject 36aa2282-d745-43ca-84d2-998a78e39d51
Factory<T>::Create()
MyClass created
MyClassFactory::Create()
MyClass created
Singleton<T>::ValueMyClass is already created
Singleton<T, F>::ValueMyClass is already created

Singleton implementation using generics

I did this as an exercise just to practice/improve using generics.

New LockerObject 36aa2282-d745-43ca-84d2-998a78e39d51
Factory<T>::Create()
MyClass created
MyClassFactory::Create()
MyClass created
Singleton<T>::ValueMyClass is already created
Singleton<T, F>::ValueMyClass is already created
Rollback to Revision 2
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

UPDATE: I chagned the design today so only one instance of T gets created irrespective of IFactory<T> usage by inserting another base class.

void Main()
{
    var a = Singleton<MyClass>.Value;
    var b = Singleton<MyClass, MyClassFactory>.Value;
    var c = Singleton<MyClass>.Value;
    var d = Singleton<MyClass, MyClassFactory>.Value;
    var e = Singleton<MyOtherClass>.Value;
    var f = Singleton<MyOtherClass>.Value;
    var g = Singleton<MyOtherClass, MyOtherFactory>.Value;
    var h = Singleton<MyOtherClass, MyOtherFactory>.Value;
}

class SingletonBase
{
    protected static object Locker = new LockerObject();
}

class SingletonValue<T>Singleton<T> : SingletonBase
{
   where protectedT static: Tnew() StaticT;
}
{
class Singleton<T> : SingletonValue<T> wherestatic T : new() StaticT;
{    
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = Activator.CreateInstance<Factory<T>>().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}

class Singleton<T, F> : SingletonValue<T>SingletonBase where T : new() where F : IFactory<T>, new()
{
    static T StaticT;
    
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = new F().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T, F>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}

class LockerObject
{
    Guid myGUID;
    public LockerObject()
    {
        this.myGUID = Guid.NewGuid();
        Console.WriteLine ("New LockerObject " + this.myGUID.ToString());
    }
}

interface IFactory<T>
{
    T Create();
}

class Factory<T> : IFactory<T> where T : new()
{
    public T Create()
    {
        Console.WriteLine ("Factory<T>::Create()");  
        return new T();
    }
}

class MyClassFactory : IFactory<MyClass>
{
    public MyClass Create()
    {
        Console.WriteLine ("MyClassFactory::Create()");    
        return new MyClass();
    }
}

class MyClass
{
    public MyClass()
    {
        Console.WriteLine ("MyClass created");
    }
}


class MyOtherClass
{
    public MyOtherClass()
    {
        Console.WriteLine ("MyOtherClass created");
    }
}

class MyOtherFactory : IFactory<MyOtherClass>
{
    public MyOtherClass Create()
    {
        Console.WriteLine ("MyOtherFactory::Create()");    
        return new MyOtherClass();
    }
}

Output::

New LockerObject aa1a940336aa2282-621fd745-43f943ca-bbaf84d2-449c84826cba998a78e39d51
Factory<T>::Create()
MyClass created
Singleton<T, F>::ValueMyClass is already created
Singleton<T>::ValueMyClass is already created
Singleton<T, F>::ValueMyClass is already created
Factory<T>MyClassFactory::Create()
MyOtherClassMyClass created
Singleton<T>::ValueMyOtherClass is already created
Singleton<T, F>::ValueMyOtherClassValueMyClass is already created
Singleton<T, F>::ValueMyOtherClassValueMyClass is already created

UPDATE: I chagned the design today so only one instance of T gets created irrespective of IFactory<T> usage by inserting another base class.

void Main()
{
    var a = Singleton<MyClass>.Value;
    var b = Singleton<MyClass, MyClassFactory>.Value;
    var c = Singleton<MyClass>.Value;
    var d = Singleton<MyClass, MyClassFactory>.Value;
    var e = Singleton<MyOtherClass>.Value;
    var f = Singleton<MyOtherClass>.Value;
    var g = Singleton<MyOtherClass, MyOtherFactory>.Value;
    var h = Singleton<MyOtherClass, MyOtherFactory>.Value;
}

class SingletonBase
{
    protected static object Locker = new LockerObject();
}

class SingletonValue<T> : SingletonBase
{
    protected static T StaticT;
}

class Singleton<T> : SingletonValue<T> where T : new() 
{    
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = Activator.CreateInstance<Factory<T>>().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}

class Singleton<T, F> : SingletonValue<T> where T : new() where F : IFactory<T>, new()
{
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = new F().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T, F>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}

class LockerObject
{
    Guid myGUID;
    public LockerObject()
    {
        this.myGUID = Guid.NewGuid();
        Console.WriteLine ("New LockerObject " + this.myGUID.ToString());
    }
}

interface IFactory<T>
{
    T Create();
}

class Factory<T> : IFactory<T> where T : new()
{
    public T Create()
    {
        Console.WriteLine ("Factory<T>::Create()");  
        return new T();
    }
}

class MyClassFactory : IFactory<MyClass>
{
    public MyClass Create()
    {
        Console.WriteLine ("MyClassFactory::Create()");    
        return new MyClass();
    }
}

class MyClass
{
    public MyClass()
    {
        Console.WriteLine ("MyClass created");
    }
}


class MyOtherClass
{
    public MyOtherClass()
    {
        Console.WriteLine ("MyOtherClass created");
    }
}

class MyOtherFactory : IFactory<MyOtherClass>
{
    public MyOtherClass Create()
    {
        Console.WriteLine ("MyOtherFactory::Create()");    
        return new MyOtherClass();
    }
}

Output:

New LockerObject aa1a9403-621f-43f9-bbaf-449c84826cba
Factory<T>::Create()
MyClass created
Singleton<T, F>::ValueMyClass is already created
Singleton<T>::ValueMyClass is already created
Singleton<T, F>::ValueMyClass is already created
Factory<T>::Create()
MyOtherClass created
Singleton<T>::ValueMyOtherClass is already created
Singleton<T, F>::ValueMyOtherClass is already created
Singleton<T, F>::ValueMyOtherClass is already created
void Main()
{
    var a = Singleton<MyClass>.Value;
    var b = Singleton<MyClass, MyClassFactory>.Value;
    var c = Singleton<MyClass>.Value;
    var d = Singleton<MyClass, MyClassFactory>.Value;
    var e = Singleton<MyOtherClass>.Value;
    var f = Singleton<MyOtherClass>.Value;
    var g = Singleton<MyOtherClass, MyOtherFactory>.Value;
    var h = Singleton<MyOtherClass, MyOtherFactory>.Value;
}

class SingletonBase
{
    protected static object Locker = new LockerObject();
}

class Singleton<T> : SingletonBase where T : new() 
{
    static T StaticT;
    
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = Activator.CreateInstance<Factory<T>>().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}

class Singleton<T, F> : SingletonBase where T : new() where F : IFactory<T>, new()
{
    static T StaticT;
    
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = new F().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T, F>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}

class LockerObject
{
    Guid myGUID;
    public LockerObject()
    {
        this.myGUID = Guid.NewGuid();
        Console.WriteLine ("New LockerObject " + this.myGUID.ToString());
    }
}

interface IFactory<T>
{
    T Create();
}

class Factory<T> : IFactory<T> where T : new()
{
    public T Create()
    {
        Console.WriteLine ("Factory<T>::Create()");  
        return new T();
    }
}

class MyClassFactory : IFactory<MyClass>
{
    public MyClass Create()
    {
        Console.WriteLine ("MyClassFactory::Create()");    
        return new MyClass();
    }
}

class MyClass
{
    public MyClass()
    {
        Console.WriteLine ("MyClass created");
    }
}


class MyOtherClass
{
    public MyOtherClass()
    {
        Console.WriteLine ("MyOtherClass created");
    }
}

class MyOtherFactory : IFactory<MyOtherClass>
{
    public MyOtherClass Create()
    {
        Console.WriteLine ("MyOtherFactory::Create()");    
        return new MyOtherClass();
    }
}

Output:

New LockerObject 36aa2282-d745-43ca-84d2-998a78e39d51
Factory<T>::Create()
MyClass created
MyClassFactory::Create()
MyClass created
Singleton<T>::ValueMyClass is already created
Singleton<T, F>::ValueMyClass is already created
improves formatting
Source Link
palacsint
  • 30.4k
  • 9
  • 82
  • 157

UPDATE: I chagned the design today so only one instance of TT gets created irrespective of IFactoryIFactory<T> usage by inserting another base class.

UPDATE: I chagned the design today so only one instance of T gets created irrespective of IFactory usage by inserting another base class.

UPDATE: I chagned the design today so only one instance of T gets created irrespective of IFactory<T> usage by inserting another base class.

deleted 70 characters in body
Source Link
Aaron Anodide
  • 1.2k
  • 9
  • 16
Loading
Tweeted twitter.com/#!/StackCodeReview/status/205074433554128896
added 677 characters in body
Source Link
Aaron Anodide
  • 1.2k
  • 9
  • 16
Loading
Source Link
Aaron Anodide
  • 1.2k
  • 9
  • 16
Loading