23.10 Performing Dynamic Invocation

 <  Day Day Up  >  

You want to call a method using late binding.


Technique

Until this point in the book, your applications always knew the data type of any objects used and their corresponding method names , events, and properties. This concept is known as early binding because the object is known to you at compile time. Late binding is the term when you create an object and call its methods at runtime without your application knowing its underlying type beforehand.

To dynamically invoke a method within a type, you must first load an assembly and find the appropriate method defined in a certain type you want to call. You use the filtering or custom searching techniques discussed in earlier recipes or enumerate all types within an assembly and search each type's methods. Once you find the appropriate method, you have a MethodInfo object, which defines an Invoke method used for dynamic invocation. The first parameter to the Invoke method is a reference to an object. Call the CreateInstance method defined in the Assembly class, and pass the name of the Type you want to create. The second parameter is an array of objects specifying the parameters to the method. Each element within the array must be the correct data type, and its index must correspond to the index of the parameter within the parameter list. The following example uses the objects created within the dynamic assemblies from the previous recipe. When a directory is specified as a command-line argument, the application enumerates all DLL assemblies and searches for a MakeHoarse method within each type defined in each assembly. If the method is found, the object is created using CreateInstance , and the MakeHoarse method is called using the Invoke method.

Listing 23.7 Loading Assemblies and Invoking Methods
 using System; using System.IO; using System.Reflection; namespace _10_DynamicInvocation {     class Class1     {         [STAThread]         static void Main(string[] args)         {             if( args.Length < 0 )             {                 ShowUsage();                 return;             }             if( Directory.Exists( args[0] ) == false)             {                 Console.WriteLine( "Cannot find specified directory." );                 return;             }             // enumerate all dll files in directory             foreach (string fileName in Directory.GetFiles( args[0], "*.dll" ))             {                 // load assembly                 Assembly curAsm = Assembly.LoadFile( fileName );                 // enumerate each type in assembly                 foreach( Type t in curAsm.GetTypes() )                 {                     // look for MakeHoarse method                     MethodInfo hoarseMethod = t.GetMethod( "MakeHoarse" );                     if( hoarseMethod == null )                         continue;                     // create object and invoke method                     object curObj = curAsm.CreateInstance( t.Name );                     hoarseMethod.Invoke( curObj, null );                 }             }         }         static void ShowUsage()         {             Console.WriteLine( "Usage: animalfarm.exe <directory>" );         }     } } 

Comments

The technique outlined in this recipe is used extensively in typeless languages such as those defined within scripting engines. Because scripting languages are not compiled, there isn't a way to interject objects referenced within class libraries, so you must use late binding to instantiate objects and call their methods. For Component Object Module (COM) objects, this feature was used extensively for scripting through the ITypeInfo and IDispatch interfaces. Although definitely not for the faint of heart, the solution worked well even though it was somewhat complicated. .NET languages, however, have a plethora of classes and methods within the Reflection namespace to enable this functionality, making the procedure much easier and saving a developer time and a little bit of sanity in the process.

The process outlined in the earlier example is just one in myriad different ways to dynamically invoke a member method. In short, all that you need is a reference to a Type object or MethodInfo object. If you have a Type object, you can call the InvokeMember method, passing the name of the method and any parameters within an object array. This circumvents any need to create an instance of an object because the method performs that for you and returns the object instance in its return value. You can also use the Invoke and InvokeMember methods to set properties and even fields within an object.

 <  Day Day Up  >  


Microsoft Visual C# .Net 2003
Microsoft Visual C *. NET 2003 development skills Daquan
ISBN: 7508427505
EAN: 2147483647
Year: 2003
Pages: 440

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net