Sunteți pe pagina 1din 11

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 1 of 11

C# Reflection and Dynamic Method Invocation


Gopalan Suresh Raj Note
To work with any of these samples, you will need the following:
.........................................Microsoft .NET SDK

The Reflection API allows a C# program to inspect and manipulate itself. It can be used to effectively find all the types in an assembly and/or dynamically invoke methods in an assembly. It can at times even be used to emit Intermediate Language code on the fly so that the generated code can be executed directly. Reflection is also used to obtain information about a class and its members. Reflection can be used to manipulate other objects on the .NET platform. The Reflection API uses the System.Reflection namespace, with the Type class to identify the Type of the Class being reflected, and fields of a struct or enum represented by the FieldInfo class, Members of the reflected class represented by the MemberInfo class, Methods of a reflected class represented by the MethodInfo class, and parameters to Methods represented by the ParameterInfo class. The Activator class's CreateInstance() method is used to dynamically invoke instances on the fly. Dynamic Invocation is very useful in providing a very late-binding architecture, where one component's runtime can be integrated with other component runtimes. We will illustrate the use of the Reflection API in three different ways: 1. Obtaining Class and Type Information from an Assembly 2. Obtaining Member Information from a Class 3. Dynamically Invoking Methods from Classes in an Assembly

Develop the Test Application


Before we start our forays into C# Reflection and Dynamic Invocation, let us develop our test applications that we'll use to test our Reflection code. Develop an interface called IBase. ImplementationOne and ImplementationTwo are classes that implement the IBase interface and are each compiled into separate assemblies.

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 2 of 11

1. Develop our Test Base Interface : IBase

IBase.cs
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: /** * File: IBase.cs * Article: C# Reflection and Dynamic Method Invocation * Copyright (c) 2000, Gopalan Suresh Raj. All Rights Reserved. */ namespace com.icommware { /** * An enumeration of Color Values */ enum ColorEnumeration { RED = 1, GREEN = 2, BLUE = 3 } /** * An Interface with 2 methods */ interface IBase { string execute (string data); double compute (int param1, double param2); } }

2. Develop a Test Implementation for the IBase Test Interface : ImplementationOne

ImplementationOne.cs
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /** * File: ImplementionOne.cs * Article: C# Reflection and Dynamic Method Invocation * Copyright (c) 2000, Gopalan Suresh Raj. All Rights Reserved. * Compile with: csc /target:library ImplementationOne.cs IBase.cs */ using System; namespace com.icommware { /** * A Class that implements the IBase interface */ class ImplementationOne : IBase { string remark = "Remark of ImplementationOne"; static int DELTAFACTOR = 10; ImplementationOne () {

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 3 of 11

21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:

Console.WriteLine ("Invoking ImplementationOne..."); } public string execute (string data) { remark = data; Console.WriteLine ("ImplementationOne's execute() remark is : {0}", remark); return remark; } public double compute (int param1, double param2) { Console.WriteLine ("ImplementationOne's compute() method invoked..."); return param1*param2*DELTAFACTOR; } } /** * A generic Structure */ struct StructOne { int x; double y; double assign () { x = 10; y = 2.8; return x*y; } } }

3. Compile the Test Application as a Library (DLL) : ImplementationOne.DLL


MS-DOS Command Prompt H:\gopalan\Reflection> H:\gopalan\Reflection>csc /target:library ImplementationOne.cs IBase.cs Microsoft (R) C# Compiler Version 7.00.8905 [NGWS runtime 2000.14.1812.10] Copyright (C) Microsoft Corp 2000. All rights reserved.

H:\gopalan\Reflection> H:\gopalan\Reflection>csc /target:library ImplementationTwo.cs IBase.cs Microsoft (R) C# Compiler Version 7.00.8905 [NGWS runtime 2000.14.1812.10] Copyright (C) Microsoft Corp 2000. All rights reserved.

H:\gopalan\Reflection>

Obtaining All Classes and Their Type Information from an Assembly


1. Develop an Application that Reflects Types: ReflectTypes

ReflectTypes.cs

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 4 of 11

1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:

/** * File: ReflectTypes.cs * Article: C# Reflection and Dynamic Method Invocation * Copyright (c) 2000, Gopalan Suresh Raj. All Rights Reserved. * Compile with: csc ReflectTypes * Run as: ReflectTypes <library> * eg., ReflectTypes ImplementationOne.dll */ using System; using System.Reflection; /** * Develop a class that can Reflect all the Types available in an Assembly */ class ReflectTypes { public static void Main (string[] args) { // List all the types in the assembly that is passed in as a parameter Assembly assembly = Assembly.LoadFrom (args[0]); // Get all Types available in the assembly in an array Type[] typeArray = assembly.GetTypes (); Console.WriteLine ("The Different Types of Classes Available in {0} are:", args Console.WriteLine ("_____"); // Walk through each Type and list their Information foreach (Type type in typeArray) { // Print the Class Name Console.WriteLine ("Type Name : {0}", type.FullName); // Print the name space Console.WriteLine ("Type Namespace : {0}", type.Namespace); // Print the Base Class Name Console.WriteLine ("Type Base Class : {0}", (type.BaseType != null)?type.BaseType Console.WriteLine ("_____"); } } }

2. Compile and Run ReflectTypes (ReflectTypes.EXE) on Our Test Library (ImplementationOne.DLL)


MS-DOS Command Prompt H:\gopalan\Reflection> H:\gopalan\Reflection>csc ReflectTypes.cs Microsoft (R) C# Compiler Version 7.00.8905 [NGWS runtime 2000.14.1812.10] Copyright (C) Microsoft Corp 2000. All rights reserved.

H:\gopalan\Reflection> H:\gopalan\Reflection>ReflectTypes ImplementationOne.dll The Different Types of Classes Available in ImplementationOne.dll are: _____ Type Name : com.icommware.ColorEnumeration Type Namespace : com.icommware Type Base Class : System.Enum

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 5 of 11

_____ Type Name : com.icommware.IBase Type Namespace : com.icommware Type Base Class : No Base Class Found... _____ Type Name : com.icommware.StructOne Type Namespace : com.icommware Type Base Class : System.ValueType _____ Type Name : com.icommware.ImplementationOne Type Namespace : com.icommware Type Base Class : System.Object _____ H:\gopalan\Reflection>

Obtaining Member Information from a Class


1. Develop an Application that Reflects Methods: ReflectMethods

ReflectMethods.cs
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: /** * File: ReflectMethods.cs * Article: C# Reflection and Dynamic Method Invocation * Copyright (c) 2000, Gopalan Suresh Raj. All Rights Reserved. * Compile with: csc ReflectMethods */ using System; using System.Reflection; namespace com.icommware { /** * An enumeration of Account Types */ enum AccountEnumeration { CHECKING = 1, SAVINGS = 2, } /** * A Class that implements the IBase interface */ class ImplementationTwo : IBase { string remark = "Remark of ImplementationTwo"; static int DELTAFACTOR = 100; ImplementationTwo () { Console.WriteLine ("Invoking ImplementationTwo ..."); } public string execute (string data) { remark = data; Console.WriteLine ("ImplementationTwo's execute() remark is : {0}", remark); return remark;

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 6 of 11

36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93:

} public double compute (int param1, double param2) { Console.WriteLine ("ImplementationTwo's compute() method invoked..."); return param1*param2*DELTAFACTOR; } } /** * A generic Structure */ struct StructTwo { double x; int y; double assign () { x = 8.2; y = 10; return x*y; } } } /** * Develop a class that can Reflect all the Types available in an Assembly */ class ReflectMethods { public static void Main (string[] args) { // retrieve information about AccountEnumeration Console.WriteLine ("Names and Values of the com.icommware.AccountEnumeration are:" Type type = typeof (com.icommware.AccountEnumeration ); // Create an instance of AccountEnumeration in Memory object accountEnum = Activator.CreateInstance (type); // List the names and values available in the AccountEnumeration enum foreach (FieldInfo fieldInfo in type.GetFields (BindingFlags.LookupAll)) { object value = fieldInfo.GetValue (accountEnum); Console.WriteLine ("{0} = {1}", fieldInfo, value); } Console.WriteLine ("_____"); // retrieve information about ImplementationTwo Class Console.WriteLine ("The Members of the com.icommware.ImplementationTwo Class are:" type = typeof (com.icommware.ImplementationTwo); // List the members of the ImplementationTwo Class foreach (MemberInfo memberInfo in type.GetFields (BindingFlags.LookupAll)) { Console.WriteLine ("{0}", memberInfo); } Console.WriteLine ("_____"); // Walk through the methods of the ImplementationTwo Class Console.WriteLine ("The Methods of the com.icommware.ImplementationTwo Class are:" foreach (MethodInfo methodInfo in type.GetMethods (BindingFlags.LookupAll)) { // Print the Method Signature

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 7 of 11

94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: } 126: }

Console.WriteLine ("{0}", methodInfo); // Walk through the method parameters foreach (ParameterInfo parameterInfo in methodInfo.GetParameters ()) { // Print the Parameter Type and the Parameter Name Console.WriteLine (" Param: {0} {1}", parameterInfo.ParameterType, parameterInfo } Console.WriteLine ("_____"); }

// retrieve information about StructTwo Class Console.WriteLine ("The Members of the com.icommware.StructTwo Class are:"); type = typeof (com.icommware.StructTwo); // List the members of the StructTwo Class foreach (MemberInfo memberInfo in type.GetFields (BindingFlags.LookupAll)) { Console.WriteLine ("{0}", memberInfo); } Console.WriteLine ("_____"); // Walk through the methods of the StructTwo Class Console.WriteLine ("The Methods of the com.icommware.StructTwo Class are:"); foreach (MethodInfo methodInfo in type.GetMethods (BindingFlags.LookupAll)) { // Print the Method Signature Console.WriteLine ("{0}", methodInfo); // Walk through the method parameters foreach (ParameterInfo parameterInfo in methodInfo.GetParameters ()) { // Print the Parameter Type and the Parameter Name Console.WriteLine (" Param: {0} {1}", parameterInfo.ParameterType, parameterInfo } Console.WriteLine ("_____"); }

2. Compile and Run ReflectMethods (ReflectMethods.EXE)


MS-DOS Command Prompt H:\gopalan\Reflection> H:\gopalan\Reflection>csc ReflectMethods.cs IBase.cs Microsoft (R) C# Compiler Version 7.00.8905 [NGWS runtime 2000.14.1812.10] Copyright (C) Microsoft Corp 2000. All rights reserved.

H:\gopalan\Reflection>ReflectMethods Names and Values of the com.icommware.AccountEnumeration are: Int32 value__ = 0 com.icommware.AccountEnumeration CHECKING = 1 com.icommware.AccountEnumeration SAVINGS = 2 _____ The Members of the com.icommware.ImplementationTwo Class are: System.String remark Int32 DELTAFACTOR _____ The Methods of the com.icommware.ImplementationTwo Class are: Double compute (Int32, Double) Param: Int32 param1 Param: Double param2

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 8 of 11

_____ System.String execute (System.String) Param: System.String data _____ Void Finalize () _____ Int32 GetHashCode () _____ Boolean Equals (System.Object) Param: System.Object obj _____ System.String ToString () _____ System.Type GetType () _____ System.Object MemberwiseClone () _____ The Members of the com.icommware.StructTwo Class are: Double x Int32 y _____ The Methods of the com.icommware.StructTwo Class are: Void Finalize () _____ Int32 GetHashCode () _____ Boolean Equals (System.Object) Param: System.Object obj _____ System.String ToString () _____ Double assign () _____ System.Type GetType () _____ System.Object MemberwiseClone () _____ H:\gopalan\Reflection>

Dynamically invoking methods from a class in an Assembly


We use Reflection to open all the Assemblies on the command line, search for Classes that implement the com.icommware.IBase interface, create an instance of that class and invoke the compute() method on the assembly. 1. Develop an Application that dynamically invokes methods from an Assembly

DynamicInvocation.cs
1: 2: 3: 4: /** * File: DynamicInvocation.cs * Article: C# Reflection and Dynamic Method Invocation * Copyright (c) 2000, Gopalan Suresh Raj. All Rights Reserved.

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 9 of 11

5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:

* Compile with: csc DynamicInvocation.cs * Run As: DynamicInvocation <library | Application...> * eg., DynamicInvocation ImplementationOne.DLL ReflectMethods.EXE */ using System; using System.Reflection; using com.icommware; class DynamicInvocation { public static void invokeProcess (string assemblyName) { Console.WriteLine ("Loading {0} into memory...", assemblyName); Assembly assembly = Assembly.LoadFrom (assemblyName); // Walk through each type in the assembly foreach (Type type in assembly.GetTypes ()) { // Pick up a class if (type.IsClass == true) { Console.WriteLine ("...Found Class : {0}", type.FullName); // If it does not implement the IBase Interface, skip it if (type.GetInterface ("com.icommware.IBase") == null) { continue; } // If however, it does implement the IBase Interface, // create an instance of the object object ibaseObject = Activator.CreateInstance (type); // Create the parameter list object[] arguments = new object [] {10, 17.11}; object result; // Dynamically Invoke the Object Console.WriteLine ("......Dynamically Invoking compute() on {0} Class", type result = type.InvokeMember ("compute", BindingFlags.Default | BindingFlags.InvokeMethod null, ibaseObject, arguments); Console.WriteLine ("......Result is: {0}", result); } } } public static void Main (string[] args) { foreach (string argument in args) { invokeProcess (argument); } } }

2. Compile and Run DynamicInvocation (DynamicInvocation.EXE)


MS-DOS Command Prompt

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 10 of 11

H:\gopalan\Reflection> H:\gopalan\Reflection>csc DynamicInvocation.cs IBase.cs Microsoft (R) C# Compiler Version 7.00.8905 [NGWS runtime 2000.14.1812.10] Copyright (C) Microsoft Corp 2000. All rights reserved.

H:\gopalan\Reflection>DynamicInvocation ImplementationOne.DLL ReflectMethods.EXE Loading ImplementationOne.DLL into memory... ...Found Class : com.icommware.ImplementationOne Invoking ImplementationOne... ......Dynamically Invoking compute() on com.icommware.ImplementationOne Class ImplementationOne's compute() method invoked... ......Result is: 1711 Loading ReflectMethods.EXE into memory... ...Found Class : com.icommware.ImplementationTwo Invoking ImplementationTwo ... ......Dynamically Invoking compute() on com.icommware.ImplementationTwo Class ImplementationTwo's compute() method invoked... ......Result is: 17110 ...Found Class : ReflectMethods H:\gopalan\Reflection> H:\gopalan\Reflection>

Download the entire source code as a zip file.

click here to go to

My Advanced C#/.NET Tutorial Page...

About the Author...


Gopalan Suresh Raj is a Software Architect, Developer and an active Author. He is contributing author to a couple of books "Enterprise Java Computing-Applications and Architecture" and "The Awesome Power of JavaBeans". His expertise spans enterprise component architectures and distributed object computing. Visit him at his Web Cornucopia site (http://www.execpc.com/~gopalan) or mail him at gopalan@execpc.com.

This site was developed and is maintained by Gopalan Suresh Raj This page has been visited times since October 19, 2000. Last Updated : Oct If you have any questions, comments, or problems regarding this site, please write 19, '00 to me I would love to hear from you.
Copyright (c) 1997-2000, Gopalan Suresh Raj - All rights reserved. Terms of use.

Go to the Component

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

C# Reflection and Dynamic Method Invocation by Gopalan Suresh Raj

Page 11 of 11

All products and companies mentioned at this site are trademarks of their respective owners.

http://my.execpc.com/~gopalan/dotnet/reflection.html

8/13/2011

S-ar putea să vă placă și