2

I have my own (simple, without threading safety) generic singleton class as below:

public class GenericSingleton<T> where T : class
{
    private static T uniqueInstance = null;
    private GenericSingleton() { }

    public static T getInstance()
    {
        if (uniqueInstance == null)
        {
            Type t = typeof(T);
            uniqueInstance = (T)Activator.CreateInstance(t);

        }
        return uniqueInstance;
    }

}

In other class, I would like create my generic class:

public class GenericFactory
{
    public object CreateObject(string TypeName, bool IsSingleton, params object[] Parameters)
    {
        if (IsSingleton)
        {
            Type genericType = typeof(GenericSingleton<>);
            Type typeArgs =  Type.GetType(TypeName);
            Type GenSinType = genericType.MakeGenericType(typeArgs);
            object o = Activator.CreateInstance(GenSinType);
            return o;
        }
        else
        {
            return Activator.CreateInstance(Type.GetType(TypeName), Parameters);
        }

    }

It is working, if I use it by

 GenericFactory gf = new GenericFactory();
    List<int> w = (List<int>)gf.CreateObject("System.Collections.Generic.List`1[System.Int32]", false, new int[] { 10, 22 });
            Console.WriteLine(w[1]+w[0]);
            Console.WriteLine(w.GetType());

Unfortunately, if I do

object test = gf.CreateObject("System.String", true, 7);

I got exepction:

An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll

Additional information: Constructor on type 'System.String' not found.

Furthermore, If I use it to create generic singleton, for example as:

List<int> ww = (List<int>)gf.CreateObject("System.Collections.Generic.List`1[System.Int32]", true, new int[] { 10, 22 });

I got next exception:

An unhandled exception of type 'System.MissingMethodException' occurred in mscorlib.dll

Additional information: No parameterless constructor defined for this object.

Could you tell me what is wrong and how can I make it better?

makcis
  • 125
  • 2
  • 10
  • 1
    By the way, I can only guess at what you're trying to achieve with this design, but you might want to look into IoC containers such as Ninject, StructureMap or Castle Windsor to see if they can do it for you – Ben Aaronson Mar 30 '14 at 11:17

1 Answers1

1

The problem is this line:

object o = Activator.CreateInstance(GenSinType);

You're trying to create an instance of your singleton class, but the whole point of the singleton pattern is that you can't do that from outside the class itself. You made the constructor private, so Activator can't access it

What you probably want to do is, in place of that line, invoke the static method on your generic type. See this question for an example.

In general you make life very difficult for yourself by requiring that you can get an instance of the type from the string representation of its name, rather than from an actual type object. Unless it's really essential, you should probably try not to do this.

Community
  • 1
  • 1
Ben Aaronson
  • 6,955
  • 2
  • 23
  • 38
  • Why I can'not write simply return GenericSingleton.getInstance(); – makcis Mar 30 '14 at 11:02
  • 1
    @makcis You can't do that in C#. You can write `GenericSingleton` but not `GenericSingleton` or `Type myType = typeof(int); GenericSingleton`. I believe this is because the generic type arguments should be known at compile-time, whereas if you used a Type object, the actual type it refers to would only be known at runtime. Hence having to use reflection with .MakeGenericType – Ben Aaronson Mar 30 '14 at 11:09
  • I still have any idea how to use here Invoke method. – makcis Mar 30 '14 at 12:24
  • @makcis What aren't you understanding about it? – Ben Aaronson Apr 01 '14 at 15:27