/* Mastering Visual C# .NET by Jason Price, Mike Gunderloy Publisher: Sybex; ISBN: 0782129110 */ /* Example17_6 illustrates runtime type invocation */ using System; using System.Reflection; public class Example17_6 { public static void Main(string[] args) { RandomSupplier rs; RandomMethod rm; // iterate over all command-line arguments foreach(string s in args) { Assembly a = Assembly.LoadFrom(s); // Look through all the types in the assembly foreach(Type t in a.GetTypes()) { rs = (RandomSupplier) Attribute.GetCustomAttribute( t, typeof(RandomSupplier)); if(rs != null) { // find the method in this class. assume that // the class only contains a single method. // can't use GetMethod() because we don't know // what the method is named foreach(MethodInfo m in t.GetMethods()) { rm = (RandomMethod) Attribute.GetCustomAttribute( m, typeof(RandomMethod)); if(rm != null) { // create an instance of the class Object o = Activator.CreateInstance(t); // create an empty arguments array Object[] aa = new Object[0]; // invoke the method int i = (int) m.Invoke(o, aa); Console.WriteLine("Class {0} in {1} returned {2}", t, s, i); } } } } } } } /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /* Mastering Visual C# .NET by Jason Price, Mike Gunderloy Publisher: Sybex; ISBN: 0782129110 */ /* Example17_5a compiles into a library defining the RamdomSupplier attribute and the RandomMethod attribute */ using System; // declare an attribute named RandomSupplier [AttributeUsage(AttributeTargets.Class)] public class RandomSupplier : Attribute { public RandomSupplier() { // doesn't have to do anything // we just use this attribute to mark selected classes } } // declare an attribute named RandomMethod [AttributeUsage(AttributeTargets.Method )] public class RandomMethod : Attribute { public RandomMethod() { // doesn't have to do anything // we just use this attribute to mark selected methods } } //=================================================== /* Example17_5b implements one class to supply random numbers */ // flag the class as a random supplier [RandomSupplier] public class OriginalRandom { [RandomMethod] public int GetRandom() { return 5; } } //=================================================== /* Example17_5c implements one class to supply random numbers */ using System; // flag the class as a random supplier [RandomSupplier] public class NewRandom { [RandomMethod] public int ImprovedRandom() { Random r = new Random(); return r.Next(1, 100); } } // this class has nothing to do with random numbers public class AnotherClass { public int NotRandom() { return 1; } } //=================================================== /* Example17_5d illustrates runtime type discovery */ using System; using System.Reflection; class Example17_5d { public static void Main(string[] args) { RandomSupplier rs; RandomMethod rm; // iterate over all command-line arguments foreach(string s in args) { Assembly a = Assembly.LoadFrom(s); // Look through all the types in the assembly foreach(Type t in a.GetTypes()) { rs = (RandomSupplier) Attribute.GetCustomAttribute( t, typeof(RandomSupplier)); if(rs != null) { Console.WriteLine("Found RandomSupplier class {0} in {1}", t, s); foreach(MethodInfo m in t.GetMethods()) { rm = (RandomMethod) Attribute.GetCustomAttribute( m, typeof(RandomMethod)); if(rm != null) { Console.WriteLine("Found RandomMethod method {0}" , m.Name ); } } } } } } }