Need help with Activator.CreateInstance()

G

Guest

I'm trying to dynamically create an instance of of a class, and it's always
failing. I'm using the Activator.CreateInstance( Type, Object[] ) overload.

The class I'm trying to instaniate and call a method from is a public class
from another project in the solution.

The Assembly is loaded fine, but whenever I try to instaniate the class, I
get a MissingMethodException exception, stating that, "Constructor on type
'...' not found". The class is found in the list of classes, and the method
is found in the list of methods.

On step-through debugging, the parameters I pass to the CreateInstance()
method are correct -- that is, the first parameter is the correct class type
and the second parameter is an array of objects that match the only public
constructor of the class I'm trying to instantiate.

Does anyone have any idea why, when everything seems correct, I'm still
getting this exception?
 
M

Mattias Sjögren

Can you post some code that reproduces the behavior you're seeing?


Mattias
 
J

Jon Skeet [C# MVP]

Quimbly said:
I'm trying to dynamically create an instance of of a class, and it's always
failing. I'm using the Activator.CreateInstance( Type, Object[] ) overload.

The class I'm trying to instaniate and call a method from is a public class
from another project in the solution.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
C

chris martin

I'm trying to dynamically create an instance of of a class, and it's
always failing. I'm using the Activator.CreateInstance( Type,
Object[] ) overload.

The class I'm trying to instaniate and call a method from is a public
class from another project in the solution.

The Assembly is loaded fine, but whenever I try to instaniate the
class, I get a MissingMethodException exception, stating that,
"Constructor on type '...' not found". The class is found in the list
of classes, and the method is found in the list of methods.

On step-through debugging, the parameters I pass to the
CreateInstance() method are correct -- that is, the first parameter is
the correct class type and the second parameter is an array of objects
that match the only public constructor of the class I'm trying to
instantiate.

Does anyone have any idea why, when everything seems correct, I'm
still getting this exception?

Are you certain that you have a constructor in the class that accepts the
objects in the exact order that you are passing them to CreateInstance?

Example:

public class Test
{
public static void Main()
{
Test c = new Test();
c.Run();
Console.ReadLine();
}

public void Run()
{

//This will work.
try
{
one = Activator.CreateInstance(typeof(MyClass), new Object[]{"one", "two"})
as MyClass;
}
catch(Exception e)
{
Console.WriteLine(e);
}

//This will work.
try
{
one = Activator.CreateInstance(typeof(MyClass), new Object[]{"one", 2})
as MyClass;
}
catch(Exception e)
{
Console.WriteLine(e);
}

//This will NOT work.
try
{
one = Activator.CreateInstance(typeof(MyClass), new Object[]{"one"}) as
MyClass;
}
catch(Exception e)
{
Console.WriteLine(e);
}
}
}

public class MyClass
{
public MyClass(string one, string two)
{
Console.WriteLine(one + " and " + two);
}

public MyClass(string one, int two)
{
Console.WriteLine(one + " and " + two);
}
 
G

Guest

Ok, here's my example... It's not the real code, but it's a parallel,
simplified version. Everything is part of the same solution.

//In Project 1:
public class Info
{
// ...
}

public class AssemblyLoader
{
//...
public bool LoadAssembly(
string assemblyName,
string assemblyPath,
string className,
object[] constructorParams,
string methodName,
object[] methodParams) {

BindingFlags flags = (BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Static | BindingFlags.Instance |
BindingFlags.DeclaredOnly);

if ((assemblyName == "") ||
(className == "") ||
(methodName == ""))
{
return false;
}

try
{
assemblyToLoad = Assembly.LoadFrom(assemblyPath +
assemblyName + ".dll");
success = true;
}
catch (Exception ex)
{
// Log error
//...

return false;
}

// Now find the proper class and method
Type classTypeToInstantiate = null;
MethodInfo methodInfoToInstantiate = null;
bool success = false;

foreach (Type classType in assemblyToLoad.GetTypes())
{
// Does the current class have the proper name?
if (classType.Name.ToString().ToUpper() !=
className.ToUpper())
{
continue;
}

// Found a good class to use
classTypeToInstantiate = classType;

// Check all the methods in the class for a matching one
foreach (MethodInfo mi in classType.GetMethods(flags))
{
// Does the method have the proper name?
if (mi.Name.ToString().ToUpper() == methodName.ToUpper())
{
methodInfoToInstantiate = mi;
break;
}
}
}

// Did we find a class and method to call
if (classTypeToInstantiate == null || methodInfoToInstantiate ==
null)
{
return false;
}

// OK, now try to call the method
try
{
//Found the class, now instantiate it
classInstance = Activator.CreateInstance(
classTypeToInstantiate, // Class type to instantiate
constructorParameters); // Arguments

// If class has been instantiated
if (classInstance != null)
{
object retObj =
methodInfoToInstantiate.Invoke(classInstance, methodParameters);

// Got this far, then ok
success = true;
}
else
{
success = false;
}
}
catch (Exception ex)
{
success = false;
}

return success;
}



//In Project 2:
public class MyAssembly
{
private MyAssembly() {}

public MyAssembly(AssemblyLoader loader, Info info)
{
//...
}
}

There it is, basically, minus most of my error handling and such. I always
get the exception on the Activator.CreateInstance() call.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top