
Introduction
I had posted this question in the C# message board. And thanks to Daniel have found a solution to that.
"Hey Everyone, I am new to C#. I am writing a small application. This application will read a method name from a flat file. Then call the method in another class library with the same name as the one read. Example, I have a method "add" in the flat file and the other library is "Math", then my aplpication should call "Math.add", the other library may change and so the flat file. This is something similar to dlsym that I used in my C/C++ programs on Unix. Can something similar be done here.
Thanks in advance, Regards, Jitesh"
Let us understand a sample application of this topic first, in order to understand the topic.
Application
Suppose you wanted to write an engine which searches in a database using some search criteria. Let's call this criteria "SomeFunduCriterea". We have two options for implementing this criteria.
Option 1: Put it into the engine itself. The problem with this is, _you_ have to modify the source for the engine in case the criteria changes. If some one else comes up with some other criteria, he will have to get the code from you and modify it.
Option 2: Make a class library, which is a collection of such criteria. Your engine would simply use this library. Now your engine can be distributed as a binary. And the criteria library as source. So any one could add their own criteria to it and still use the engine without any changes.
Option 2 is always a much better option. The issue here will be when we try to call the functions in our criteria library from the engine. How will the engine know at run time what to call in the criteria library? Let us look at the solution.
Solution
The methods that the engine should call will be in a flat file (mostly an XML file). This will be the input file to the engine. The file will also contain the arguments to the method. We will use the System.Reflection namespaces' MethodInfo class to invoke our user method in the criteria class.
How to do this?
We will see a sample example to check out how this can be achieved. We have our user method, in a class called CExternal.
public class CExternal
{
public CExternal()
{}
public string Fullname(string firstname, string lastname)
{
return (firstname + lastname);
}
}
Our user method here is the FullName method, which returns concatenation of the two arguments firstname and lastname. This class can be in a separate class library.
The next class that we need to write is the CInvoker, which invokes the method.
public class CInvoker
{
public CInvoker()
{}
public object InvokeMethod (string method, object[] args)
{
CExternal objExternal = new CExternal();
Type typExternal = Type.GetType("MethodInvoke.CExternal");
MethodInfo methodInf = typExternal.GetMethod(method);
object ret = methodInf.Invoke(objExternal, args);
return ret;
}
}
The Simple Steps
- First of all we create an object of the
CExternal class.
- Get the type of the
CExternal class.
- On this type object call
GetMethod. This takes the string name of the method. (Remember our XML file i.e. input to the engine has this name). This method returns us our MethodInfo object. (MethodInfo inherits from the MethodBase class.)
- And finally call the
Invoke method. We will pass it, our CExternal object (line 1) and an object[] of arguments.
And finally the driver for this Invoke class. I.e. our main method in CMain class.
public class CMain
{
public CMain()
{}
public static void Main()
{
CInvoker ink = new CInvoker();
string[] args = {"Jitesh" , "patil"};
ink.InvokeMethod("Fullname", args);
}
}
Simple isn't it.
Thanks to
- Daniel Turini.
- Microsoft
System.Reflection.MethodBase and MethodInfo.
Reference
MSDN link to MethodBase.Invoke() method.