|
Thank You ! 
|
|
|
|
|
It's 8 years after you wrote this article and I just recently needed such a solution. Many, many thanks.
|
|
|
|
|
This was exactly what I was looking for, explained clearly and works a treat 
|
|
|
|
|
Call a Method in Another Project and Namespace Worked fine for me.
thanks a lot 
|
|
|
|
|
hii.i am kannan
can I use this Dynamically Invoke A Method, in genaric handler in asp.net ,for setting Model ,View ,Controller dynamically ??
|
|
|
|
|
Converted this code to VB.NET 2010.
The author should point out that this code only works when the method is a Static method (C#) or a Shared method (VB).
I couldn't get it to work otherwise.
|
|
|
|
|
great...code
langa manish
|
|
|
|
|
Hi Matt,
how to do the same way for the web service and web method?
Your immediate reply would be much appreciated.
Thank you very much dude,
|
|
|
|
|
how do i cater this problem?
MethodA maybe receives only 1 param of type string but MethodB receives 2 params of type string and integer..
how to solve this?
|
|
|
|
|
 I built up a class for housing little helpful functions for something such as that occasion.
The following two functions will help with this. (one is for use with static methods and one is for use with methods belonging to an instance of a class.
To Execute a Static Method:
/// <summary>
/// executes a method belonging to an external namespace/project. it allows the use for any number of parameters (as objects)
/// </summary>
/// <param name="assembly" type="string">the project the namespace belongs to</param>
/// <param name="namesSpace" type="string">the namespace for which to find the class and method</param>
/// <param name="typeName" type="string">the class type that the method belongs to</param>
/// <param name="methodName" type="string">name of the method</param>
/// <param name="parameters" type="params object[]">one or more parameters for the method you wish to call</param>
/// <returns type="object">returns an object if it has anything to return</returns>
public static object execStaticString(string assembly, string nameSpace, string typeName, string methodName, params object[] parameters)
{
//get the type of the class
Type theType = Type.GetType(nameSpace + "." + typeName + "," + assembly);
//invoke the method from the string. if there is anything to return, it returns to obj.
object obj = theType.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, parameters);
//return the object if it exists
return obj;
}//end static object execExtString(string,string,string,string,params object[])
To call the above function for MethodA, you would do something like:
execStaticString("theAssembly", "theNamespace", "theClass", "MethodA", param1);
To call the above function for MethodB, you would do something like:
execStaticString("theAssembly", "theNamespace", "theClass", "MethodB", param1, param2);
To Execute a Non-Static Method:
/// <summary>
/// executes a method belonging to an external namespace/project. it allows the use for any number of parameters (as objects)
/// </summary>
/// <param name="classObject" type="object">the class instantiation that the method belongs to</param>
/// <param name="methodName" type="string">name of the method</param>
/// <param name="parameters" type="params object[]">one or more parameters for the method you wish to call</param>
/// <returns type="object">returns an object if it has anything to return</returns>
public static object execExtString(object classObject, string methodName, params object[] parameters)
{
//invoke the method from the string. if there is anything to return, it returns to obj.
object obj = classObject.GetType().InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, classObject, parameters);
//return the object
return obj;
}//end static object execExtString(string,string,string,string,params object[])
To call the above function for MethodA, you would do something like:
execExtString(this, "MethodA", "testing...1,2,3");
To call the above function for MethodB, you would do something like:
execExtString(this, "MethodB", "testing...1,2,3", 456);
----------------------
Nathan VanBuskirk
C++, C# Developer
http://Seriussoft.com
|
|
|
|
|
Many Thanks for that piece of code
Godwin
|
|
|
|
|
Glad to be of some help.
----------------------------
Nathan VanBuskirk
C++, C# Developer
http://Seriussoft.com
|
|
|
|
|
I was going to suggest using a params array of type object[], as well.
Also,
dudeserius wrote: Type theType = Type.GetType(nameSpace + "." + typeName + "," + assembly);
String.Format that please. Adding strings together like that would create multiple string objects whereas a String.Format would create one and simply combine then together.
Another alternative would be:
Type theType = Type.GetType(String.Join(".", new string[] { nameSpace, typeName }));
Or, String.Format:
Type theType = Type.GetType(String.Format("{0}.{1}, {2}", nameSpace, typeName, assembly));
Thanks,
-Zack
|
|
|
|
|
 I added the following two mods for these cases mentioned approve to share. Great example.
using System;
using System.Linq;
using System.Reflection;
namespace BLL
{
public class TypeUtils
{
public static string InvokeStringMethod(string typeName, string methodName)
{
Type calledType = Type.GetType(typeName);
String s = (String)calledType.InvokeMember(
methodName,
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null,
null,
null);
return s;
}
public static string InvokeStringMethod2(string typeName, string methodName, string stringParam)
{
Type calledType = Type.GetType(typeName);
String s = (String)calledType.InvokeMember(
methodName,
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null,
null,
new Object[] { stringParam });
return s;
}
public static string InvokeStringMethod3(string assemblyName, string namespaceName, string typeName, string methodName)
{
Type calledType = Type.GetType(String.Format("{0}.{1},{2}", namespaceName, typeName, assemblyName));
String s = (String)calledType.InvokeMember(
methodName,
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null,
null,
null);
return s;
}
#region AddedSection
public static string InvokeStringMethod4(string assemblyName, string namespaceName, string typeName, string methodName, string stringParam)
{
Type calledType = Type.GetType(String.Format("{0}.{1},{2}", namespaceName, typeName, assemblyName));
String s = (String)calledType.InvokeMember(
methodName,
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null,
null,
new Object[] { stringParam });
return s;
}
public static string InvokeStringMethod5(string assemblyName, string namespaceName, string typeName, string methodName, string stringParam)
{
Type calledType = Type.GetType(String.Format("{0}.{1},{2}", namespaceName, typeName, assemblyName));
String s = null;
if (MethodHasParams(assemblyName, namespaceName, typeName, methodName))
{
s = (String)calledType.InvokeMember(
methodName,
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null,
null,
new Object[] { stringParam });
}
else
{
s = (String)calledType.InvokeMember(
methodName,
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null,
null,
null);
}
return s;
}
public static bool MethodHasParams(string assemblyName, string namespaceName, string typeName, string methodName)
{
bool HasParams;
string name = String.Format("{0}.{1},{2}", namespaceName, typeName, assemblyName);
Type calledType = Type.GetType(name);
MethodInfo methodInfo = calledType.GetMethod(methodName);
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length > 0)
{
HasParams = true;
}
else
{
HasParams = false;
}
return HasParams;
}
#endregion
}
}
|
|
|
|
|
Say I have Class A and it has 2 properties (Prop1 and Prop2) and 2 methods (DoThis, DoThat).
If I have create an instance of A (objA) and then set
<br />
Prop1 = "a"<br />
Prop2 = "b"<br />
and the methods are defined as follows
<br />
Public Sub DoThis()<br />
Prop1 += "c"<br />
End Sub<br />
<br />
Public Sub DoThat()<br />
Prop2 += "2"<br />
End Sub<br />
If I want to have ClassA dynamically invoke DoThis() using the method you outlined (via reflection) It will create a new instance of ClassA (objB) and invoke the method. You will get a null ref exception, because objA.Prop1 will not be accessible by objB. This example is oversimplified, but think in the case of ASP.NET. If I want to access a method that is on the same page, I can, but I will not have access to any of the original pages methods and properties (all the web form control values). I can add parameters to the dynamically executed method so I have some kind of workaround, but do you know how I can best get around this?
|
|
|
|
|
actually, the solution is not too different from his approach, but I must apologize, for I only know how to do this in c#. Hopefully it will lead you in the right direction.
//using objects for a generic approach that works with void and value returning methods
object obj = this.GetType().InvokeMember("DoThis", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, this, null);
//if you want to invoke a method that is publicly accessible and owned by another class
//let's say you are in ClassA and you have instantiated another ClassA by the name of objB
object obj = objB.GetType().InvokeMember("DoThis", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public, null, objB, null);
---------------------
Nathan VanBuskirk
C++, C# Developer
http://Seriussoft.com
|
|
|
|
|
My code is -:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
namespace ForPrintPre
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
object obj = this.GetType().InvokeMember(textBox1.Text, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, null);
}
public void CallMe()
{
MessageBox.Show("In Call Me");
}
}
}
Quote: object obj = this.GetType().InvokeMember(textBox1.Text, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, null);
At the runtime I'm getting error that "Method 'ForPrintPre.Form1.CallMe()' not found." 
|
|
|
|
|
I don't have an instance of visual studio on this machine, but I have a guess just from looking at your code.
You reference that the BindingFlags should contain BindingFlags.Static, but your CallMe method is an instance method. Change the method signature to the following and run that again:
public static void CallMe()
{
MessageBox.Show("In Call Me");
}
If you intended for the method to be an instance method, then remove the BindingFlags.Static flag and add this to the 2nd from last parameter in the InvokeMember call:
this.GetType().InvokeMember(textBox1.Text, BindingFlags.InvokeMethod | BindingFlags.Public, null, this, null);
Hope that helps
----------------------------
Nathan VanBuskirk
C++, C# Developer
http://Seriussoft.com
|
|
|
|
|
thanks for your Reply....
Sir still I'm getting Error..
My Code is -:
public partial class dynamicMethodCall : Form
{
public dynamicMethodCall()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
this.GetType().InvokeMember(textBox1.Text, BindingFlags.InvokeMethod | BindingFlags.Public, null, this, null);
}
catch {
MessageBox.Show("The function Not found..");
}
}
public void CallMe()
{
MessageBox.Show("In Call Me Method.");
}
}
when i run this code, The message Box displayed("The Function Not Found")...
|
|
|
|
|
I ran your code through LinqPad, and it seems I deduced the problem. Your binding flags needs to also include instance methods
this.GetType().InvokeMember(textBox1.Text, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, this, null);
That should do the trick for you. I apologize for just now responding. I've been away from the internet for a while.
----------------------------
Nathan VanBuskirk
C#, VB.NET, C++, Java Developer
http://Seriussoft.com
|
|
|
|
|
Thank you. That's exact what i've been searching for last week 
|
|
|
|
|
Matt,
Thanks for this contribution. Cool article.
"In quiet and silence, the truth is made clear."
|
|
|
|
|