Reputation: 125
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?
Upvotes: 2
Views: 581
Reputation: 6975
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.
Upvotes: 1