Dynamic list of classes
-
Hello, I am looking for a way in C# to be able to programatically build a list of available classes in the applcation that I can search the list and execute a desired class method based on a passed parameter to the program. I could do this by building a case statement with all available classes, but would like it to be more dynamic. Thanks
-
Hello, I am looking for a way in C# to be able to programatically build a list of available classes in the applcation that I can search the list and execute a desired class method based on a passed parameter to the program. I could do this by building a case statement with all available classes, but would like it to be more dynamic. Thanks
Hi! You can try this code snippit, I think it's what you want to do. I made this type of thing before for a Java proggie, and it was even easier in C#! Good Luck! A few runs look like: ------------------------------ RunArbitraryClasss.exe RunArbitraryClasss.NonRunnableClass arg1 arg2 Unhandled Exception: System.Exception: A class was specified that is not subclassed from ValidRunnableClass! at RunArbitraryClasss.RunArbitraryClasss.Run(String[] args) in c:\source\automation\runarbitraryclasss\runarbitraryclasss.cs:line 53 at RunArbitraryClasss.RunArbitraryClasss.Main(String[] args) in c:\source\automation\runarbitraryclasss\runarbitraryclasss.cs:line 20 ------------------------------ RunArbitraryClasss.exe RunArbitraryClasss.RunnableClass arg1 arg2 I'm a runnable class: arg1 arg2 Here's the source! --------------------------------------------------------------
using System; using System.Reflection; namespace RunArbitraryClasss { /// /// Summary description for Class1. /// class RunArbitraryClasss { /// /// The main entry point for the application. /// [STAThread] static int Main(string[] args) { // Get the program running. RunArbitraryClasss oRunArbitraryClasss = new RunArbitraryClasss(); return(oRunArbitraryClasss.Run(args)); } public int Run(string[] args) { // Get a list of valid types. Type [] aTypes = System.Reflection.Assembly.GetExecutingAssembly().GetTypes(); foreach(Type oCurrType in aTypes) { if(oCurrType.ToString() == args[0] && oCurrType.IsSubclassOf(Type.GetType("RunArbitraryClasss.ValidRunnableClass"))) { // Get the constructor for the class to invoke the run method on. ConstructorInfo ci = oCurrType.GetConstructor(Type.EmptyTypes); // Create an instance of the class that is derived from // ValidRunnableClass. This will give us our prototype for invoking the // Run method on the subclass. ValidRunnableClass vrc = (ValidRunnableClass) ci.Invoke(null); // Drop the first arg from the args list. string [] passArgs = new string [args.Length - 1]; int i = 0; for(i = 1; i < args.Length; i++) { passArgs[i - 1] = args[i]; } // Execute the target class. return(vrc.Run(passArgs)); } } throw new Exception("A class was specified that is not subclassed from ValidRunnableClass!"); } } abstract class ValidRunnable
-
Hi! You can try this code snippit, I think it's what you want to do. I made this type of thing before for a Java proggie, and it was even easier in C#! Good Luck! A few runs look like: ------------------------------ RunArbitraryClasss.exe RunArbitraryClasss.NonRunnableClass arg1 arg2 Unhandled Exception: System.Exception: A class was specified that is not subclassed from ValidRunnableClass! at RunArbitraryClasss.RunArbitraryClasss.Run(String[] args) in c:\source\automation\runarbitraryclasss\runarbitraryclasss.cs:line 53 at RunArbitraryClasss.RunArbitraryClasss.Main(String[] args) in c:\source\automation\runarbitraryclasss\runarbitraryclasss.cs:line 20 ------------------------------ RunArbitraryClasss.exe RunArbitraryClasss.RunnableClass arg1 arg2 I'm a runnable class: arg1 arg2 Here's the source! --------------------------------------------------------------
using System; using System.Reflection; namespace RunArbitraryClasss { /// /// Summary description for Class1. /// class RunArbitraryClasss { /// /// The main entry point for the application. /// [STAThread] static int Main(string[] args) { // Get the program running. RunArbitraryClasss oRunArbitraryClasss = new RunArbitraryClasss(); return(oRunArbitraryClasss.Run(args)); } public int Run(string[] args) { // Get a list of valid types. Type [] aTypes = System.Reflection.Assembly.GetExecutingAssembly().GetTypes(); foreach(Type oCurrType in aTypes) { if(oCurrType.ToString() == args[0] && oCurrType.IsSubclassOf(Type.GetType("RunArbitraryClasss.ValidRunnableClass"))) { // Get the constructor for the class to invoke the run method on. ConstructorInfo ci = oCurrType.GetConstructor(Type.EmptyTypes); // Create an instance of the class that is derived from // ValidRunnableClass. This will give us our prototype for invoking the // Run method on the subclass. ValidRunnableClass vrc = (ValidRunnableClass) ci.Invoke(null); // Drop the first arg from the args list. string [] passArgs = new string [args.Length - 1]; int i = 0; for(i = 1; i < args.Length; i++) { passArgs[i - 1] = args[i]; } // Execute the target class. return(vrc.Run(passArgs)); } } throw new Exception("A class was specified that is not subclassed from ValidRunnableClass!"); } } abstract class ValidRunnable
This worked on returning the class names. I now have populated a string collection with the names of the matching classes. In doing so, I ran into another question. If I have several classes that have a method of .execute(), how can I create an instance and call the .execute of the function that matches the function name that is in the string collection? for example: public class MyTestFuction { public void Execute() { // do something here } } string s = "MyTestFuction" if (s == "MyTestFuction") { //How to use the string name to //call the matching class s ????? .Execute(); }
-
This worked on returning the class names. I now have populated a string collection with the names of the matching classes. In doing so, I ran into another question. If I have several classes that have a method of .execute(), how can I create an instance and call the .execute of the function that matches the function name that is in the string collection? for example: public class MyTestFuction { public void Execute() { // do something here } } string s = "MyTestFuction" if (s == "MyTestFuction") { //How to use the string name to //call the matching class s ????? .Execute(); }
Take another look at ValidRunnableClass. It's an abstract class which exposes one method, Run(). If you change your example above a hair, to look like: public class MyTestFuction : ValidRunnableClass { // Change the Execute call to match the Run() method in ValidRunnableClass. public override void Run(string [] args) { // do something here } } Now, you have a class that has a common interface. You can add more classes at will, without having to add any switch/cases at all. Next, to cause the execution check my example again: Type [] aTypes = System.Reflection.Assembly.GetExecutingAssembly().GetTypes(); foreach(Type oCurrType in aTypes) { if(oCurrType.ToString() == args[0] && oCurrType.IsSubclassOf(Type.GetType("RunArbitraryClasss.ValidRunnableClass"))) { // Get the constructor for the class to invoke the run method on. ConstructorInfo ci = oCurrType.GetConstructor(Type.EmptyTypes); // Create an instance of the class that is derived from // ValidRunnableClass. This will give us our prototype for invoking the // Run method on the subclass. ValidRunnableClass vrc = (ValidRunnableClass) ci.Invoke(null); // Drop the first arg from the args list. string [] passArgs = new string [args.Length - 1]; int i = 0; for(i = 1; i < args.Length; i++) { passArgs[i - 1] = args[i]; } // Execute the target class. return(vrc.Run(passArgs)); } } throw new Exception("A class was specified that is not subclassed from ValidRunnableClass!");} First, you create an instance of the ValidRunnableClass interface from a System.Type object. You do this with the System.Type.GetConstructor() function. Then, you use the ConstructorInfo.Invoke() method to create a ValidRunnableClass object. Then, you call the Run() method on the ValidRunnableClass which does your work. Because you extended MyTestFunction from ValidRunnableClass, it will call the proper method in MyTestFunction automatically! Ok, I think you should be able to make it go from here. Good luck! Nick.