patd1
asked on
Running a static method dynamically
I have saved my class names and method names in a database table. Based on the case type I pickup a class name, a method name from the database into respective strings and form an Argument String . How do I run this method dynamically? Please see sample code and suggest.
Thank You.
Normally if it weren't in the database I would run like this:
With the strings coming in strings from the database I have the following code:
Thank You.
Thank You.
Normally if it weren't in the database I would run like this:
ArgumentString = "/CaseNum " + caseNo + " /Ver " + StrVer + " /TemplateID " + TemplateID + " /ReportType " + ReportType;
Name189TFConsole.TF189(ArgumentString);
With the strings coming in strings from the database I have the following code:
ArgumentString = "/CaseNum " + caseNo + " /Ver " + StrVer + " /TemplateID " + TemplateID + " /ReportType " + ReportType;
string ClassName= "Name189TFConsole";
string MethodName = "TF189";
//code to run the Method here.
Thank You.
Here is one way to do it. It might not be the best or most efficient way, but it will work:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main( string[] args )
{
string className = "Name189TFConsole";
string methodName = "TF189";
Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly();
Type[] thisTypes = thisAssembly.GetTypes();
foreach ( Type t in thisTypes )
{
if ( string.Equals( t.Name, className, StringComparison.InvariantCultureIgnoreCase ) )
{
MethodInfo[] methods = t.GetMethods();
foreach ( MethodInfo m in methods )
{
if ( string.Equals( m.Name, methodName, StringComparison.InvariantCultureIgnoreCase ) )
{
m.Invoke( null, null );
}
}
}
}
}
}
public class Name189TFConsole
{
public Name189TFConsole() { }
public static void TF189()
{
Console.WriteLine( "TF189" );
}
}
}
I suppose Dan7el raises a good point about checking the stuff actually exists. ;)
Type.GetType will get the type for you without needing to enumerate all the types in the assembly, and will ignore case. This example has a method to retrieve the corresponding MethodInfo from the Type (which is just about the same he has above), and then Invokes that MethodInfo.
Type.GetType will get the type for you without needing to enumerate all the types in the assembly, and will ignore case. This example has a method to retrieve the corresponding MethodInfo from the Type (which is just about the same he has above), and then Invokes that MethodInfo.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
string class1 = "testclass1", method1 = "testmethod", class2 = "testclass2", method2 = "othertestmethod";
Type t1 = Type.GetType(class1, false, true);
if (t1 == null)
Console.WriteLine("Could not find type {0}.", class1);
else
{
MethodInfo staticMethod = GetStaticMethod(t1, method1);
if (staticMethod == null)
Console.WriteLine("Could not find method {0}.", method1);
else
staticMethod.Invoke(t1, new object[] { });
}
Console.ReadKey();
}
static MethodInfo GetStaticMethod(Type t, string MethodName)
{
foreach (MethodInfo mi in t.GetMethods())
{
if (mi.Name.Equals(MethodName, StringComparison.InvariantCultureIgnoreCase) && mi.Attributes.HasFlag(MethodAttributes.Static))
return mi;
}
return null;
}
}
public class TestClass1
{
public static void TestMethod()
{
Console.WriteLine("Hello World");
}
}
public class TestClass2
{
public static void OtherTestMethod()
{
Console.WriteLine("Other Method");
}
}
ASKER
Thanks for the solution. I tried the one suggested by tgerbert and I get the following compilation error:
'System.Reflection.MethodA ttributes' does not contain a definition for 'HasFlag' and no extension method 'HasFlag' accepting a first argument of type 'System.Reflection.MethodA ttributes' could be found (are you missing a using directive or an assembly reference?)
Any help is highly appreciated.
Thanks You
'System.Reflection.MethodA
Any help is highly appreciated.
Thanks You
HasFlag isn't available until .Net 4.0, you need to manually check the existence of a flag yourself otherwise. Bit-wise "AND" the Attributes with MethodAttributes.Whatever - if MethodAttributes.Whatever is set the result will be non-zero.
if (aVariable & SomeEnum.SomeFlag != 0)
hasFlag = true
else
hasFlag = false
ASKER
Thanks again.
How do I pass parameters to the method?
And how would the invoke change if the method is not static?
How do I pass parameters to the method?
And how would the invoke change if the method is not static?
example:
76MapToORU Object76 = new 76MapToORU();
Object76.Run(caseNo, Ver, TemplateID, Status);
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I am getting this exception on line: Type t = Type.GetType(className, true, true);
base {System.SystemException} = {"Could not load type '76CGMapToORU ' from assembly 'Result_Generator_1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.":"76 CGMapToORU "}
My current code:
If I run the code below, it runs fine.
Thanks for your help.
base {System.SystemException} = {"Could not load type '76CGMapToORU ' from assembly 'Result_Generator_1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.":"76
My current code:
string className = "76CGMapToORU ";
string methodName = "Run";
Type t = Type.GetType(className, true, true); //I hv set throw on error to true to see the exception
....
If I run the code below, it runs fine.
76CGMapToORU 76CGMapToORUObject = new 76CGMapToORU ();
76CGMapToORUObject .Run(caseNo, Ver, TemplateID, ReportType);
Thanks for your help.
ASKER
please read as: string className = "76CGMapToORU";
There is no extra space there in the code, but I still get the exception.
There is no extra space there in the code, but I still get the exception.
ASKER
You can ignore the above messages. I appended the class name with namespace name and that worked.
Thanks for all your help.
Thanks for all your help.
Type.GetType() assumes the current assembly. If 76CGMapToORU appears in a separate assembly, will need to supply a fully-qualified type name (e.g. ClassLibrary1.Class1, ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, or get a reference to that assembly and use Assembly.GetType().
Open in new window