Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Reflection Part I: Discovery and Execution : Page 4

Many developers see reflection as something new and mysterious. In the first of this two-part article we explain reflection in the .NET Framework and demonstrate where and how you can use this new tool in your applications.

Executing Discovered Code
Discovering types at runtime is great but being able to act on those types provides the real power behind reflection. With reflection you can write code that has no idea of a given object or assembly at design time. The code you write can then create an instance of a class within a discovered assembly, find a method on that class, get the method's parameters, and execute the method. This is the ultimate in late binding: locating and executing a type at runtime. In fact, when you use basic late binding in VB, the compiler uses reflection implicitly. Let's look at how to handle this explicitly.

The process for executing discovered code follows these basic steps:
  1. Load the assembly.
  2. Find the type or class you wish to use.
  3. Create an instance of the type (or class).
  4. Find a method on the type you wish to execute.
  5. Get the method's parameters.
  6. Invoke the object's method and pass the proper parameters.
You've already seen how to load an assembly and search for types in that assembly. Once you know the type you are after, you can use the System.Activator class to return an instance of the type. You'll use one of the CreateInstance methods of the Activator class. CreateInstance allows you to specify the object you want created and optionally the parameters used in the object's constructors. Here is a simple example where an object's default constructor takes no parameters:

Dim obj As Object = _ Activator.CreateInstance(myType)

Suppose that you want to create an instance of a given object with a constructor that took parameters. You can do so by passing these values as an array to CreateInstance. Each value needs to be of the same type and in the same order of the constructor's signature. Imagine that the type you were trying to create had the following constructor:

Public Sub New(ByVal someParam As String)

Your first job would be to query the constructor for parameters. Once you've identified the constructor, you can get its parameters using the GetParameters method of the ConstructorInfo class. GetParameters will return an array of ParameterInfo objects that will let you determine a parameter's order, its name, and its data type. You can then build your own array of parameter values and pass it to CreateInstance. Here is a basic example.

Suppose you have a class called SomeClass that has a constructor that takes one parameter that is of the type String. Let's also suppose you have a reference to SomeClass called myType. Finally, let's assume you have a reference (called ci) to SomeClass' constructor as a ConstructorInfo instance. To get a list of parameters for the given constructor (ci) you call GetParameters as follows:

Dim pi() As ParameterInfo pi = ci.GetParameters()

Then you create your own array of the same size as the number of parameters returned by GetParameters.

Dim params(pi.GetUpperBound(0)) As Object

Values are set for every parameter in the array:

Dim i As Int16 For i = 0 To pi.GetUpperBound(0) If pi(i).ParameterType.Name = "String" Then params(i) = "Test" End If Next

Finally, you call CreateInstance, passing in both your type and the values for the type's constructor's parameters.

Dim o As Object = _ Activator.CreateInstance(myType, params)

Now that you have an instance (o) for your object (SomeClass), let's look at how you might execute one of its methods. The same process of querying for parameters and passing them into a constructor works for methods. Let's suppose that SomeClass has a method called SomeMethod that you want to invoke. To keep this simple let's suppose that SomeMethod takes no parameters (as this is the same process outlined above). To invoke SomeMethod you need to get a reference to the method as a MethodInfo object. You can search for methods on your type with either GetMethod or GetMethods. Let's use GetMethod and pass the method name as a string:

Dim mi As MethodInfo = _ t.GetMethod("SomeMethod")

You have both an instance to SomeClass and a reference (mi) to the method you wish to call so you can use MethodInfo.Invoke to call your target method. You'll pass your object instance that contains your method and an array of parameters that the method takes (in this case Nothing). For example:>

mi.Invoke(o, Nothing)

You've now successfully created an instance of an object not necessarily known at design time, found a method on that object, and invoked the method. You can easily extrapolate this example to create a utility such as a testing tool. Suppose that you allow a user to select an assembly. You could list all classes and methods in the given assembly. The user could select a method at run time. You could use discovered information about the class and method to present the user with a form to exercise the method. The user could then enter values for the given method and the testing tool would invoke the method and return the results—all without knowing a thing about the assembly at design time. (See Sidebar: Reflection Security)

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date