I want to load an assembly (its name is stored in a string), use reflection to check if it has a method called "CustomType MyMethod(byte[] a, int b)" and call it or throw an exception otherwise. I guess I should do something like this, but would appreciate if someone could offer same advice on how best to do it:
Assembly asm = Assembly.Load("myAssembly"); /* 1. does it matter if write myAssembly or myAssembly.dll? */
Type t = asm.GetType("myAssembly.ClassName");
// specify parameters
byte[] a = GetParamA();
int b = GetParamB();
object[] params = new object[2];
params[0] = a;
params[1] = b;
/* 2. invoke method MyMethod() which returns object "CustomType" - how do I check if it exists? */
/* 3. what's the meaning of 4th parameter (t in this case); MSDN says this is "the Object on which to invoke the specified member", but isn't this already accounted for by using t.InvokeMember()? */
CustomType result = t.InvokeMember("MyMethod", BindingFlags.InvokeMethod, null, t, params);
Is this good enough, or are there better/faster/shorter ways? What about constructors, given that these methods are not static - can they simply be ignored?
When invoking void Methods(), is it ok to just write t.InvokeMember(...) or should you always do Object obj = t.InvokeMember(...)?
Thanks in advance.
EDIT I have provided a working example as a separate answer below.
Since this seems to be a popular question, here's the complete source code example on how to do it.
Suppose we have a sample assembly, MyAssembly.dll, with a class MyClass. We wish to dynamically load it and invoke its methods. MyAssembly code:
namespace MyAssembly
{
public class MyClass
{
public int X { get; set; }
public int Y { get; set; }
public MyClass(int initialX, int initialY)
{
X = initialX;
Y = initialY;
}
public int MyMethod(int count, string text)
{
Console.WriteLine("This is a normal method.");
Console.WriteLine("Count: {0}", count);
Console.WriteLine("Text: {0}", text);
return this.X + this.Y;
}
public static void StaticMethod(int count, float radius)
{
Console.WriteLine("This is a static method call.");
Console.WriteLine("Count: {0}", count);
Console.WriteLine("Radius: {0}", radius);
}
}
}
First, we would like to create an instance of the class using the constructor MyClass(int initialX, int initialY)
, then call the method public int MyMethod(int count, string text)
. Here's how you do it from another project (e.g. a console application):
static void Main(string[] args)
{
//
// 1. Load assembly "MyAssembly.dll" from file path. Specify that we will be using class MyAssembly.MyClass
//
Assembly asm = Assembly.LoadFrom(@"C:\Path\MyAssembly.dll");
Type t = asm.GetType("MyAssembly.MyClass");
//
// 2. We will be invoking a method: 'public int MyMethod(int count, string text)'
//
var methodInfo = t.GetMethod("MyMethod", new Type[] { typeof(int), typeof(string) });
if (methodInfo == null)
{
// never throw generic Exception - replace this with some other exception type
throw new Exception("No such method exists.");
}
//
// 3. Define parameters for class constructor 'MyClass(int initialX, int initialY)'
//
object[] constructorParameters = new object[2];
constructorParameters[0] = 999; // First parameter.
constructorParameters[1] = 2; // Second parameter.
//
// 4. Create instance of MyClass.
//
var o = Activator.CreateInstance(t, constructorParameters);
//
// 5. Specify parameters for the method we will be invoking: 'int MyMethod(int count, string text)'
//
object[] parameters = new object[2];
parameters[0] = 124; // 'count' parameter
parameters[1] = "Some text."; // 'text' parameter
//
// 6. Invoke method 'int MyMethod(int count, string text)'
//
var r = methodInfo.Invoke(o, parameters);
Console.WriteLine(r);
}
Calling the static method public static void StaticMethod(int count, float radius)
looks like this:
var methodInfoStatic = t.GetMethod("StaticMethod");
if (methodInfoStatic == null)
{
// never throw generic Exception - replace this with some other exception type
throw new Exception("No such static method exists.");
}
// Specify parameters for static method: 'public static void MyMethod(int count, float radius)'
object[] staticParameters = new object[2];
staticParameters[0] = 10;
staticParameters[1] = 3.14159f;
// Invoke static method
methodInfoStatic.Invoke(o, staticParameters);