Generate and Execute Dynamic Script With .NET

What You Need
To build the samples you need Visual Studio .NET and the .NET Framework (sp1). You should have an understanding of the .NET Framework and scripting on the Windows platform.

Reflection is a powerful tool in the .NET Framework that enables type discovery, the viewing of assembly metadata, and dynamic invocation of assembly code at runtime. You can also use reflection to create object instances from types at runtime using the System.Reflection.Emit namespace. Typically, you’d use these features for creating compilers, and building development tools for evaluating compiled code?but you can also use them for generating and processing scripts.

With the dynamic invocation functions available through reflection, you can create a reference to an assembly at runtime, determine what methods of that assembly are available, and to execute one of these methods. This can be very useful for late binding and for working with assembly code from third parties where different assembly versions expose different classes and methods, yet the management of that code is not under your control. But you can also use these techniques to support script creation by users or for referencing components that may not be available at compile time. In addition, this is a useful technique for executing code generated dynamically at runtime.

To apply the reflection techniques described effectively, you need to understand the System.Reflection namespace. In this article, I’ll show you an example of dynamic script generation and invocation using Jscript.NET code.

The System.Reflection.Assembly class is one of the most important classes for implementing reflection-based techniques in your applications, because it exposes several methods for loading assemblies, which let you load a new assembly at runtime. After loading an assembly, you can use an instance of the Assembly object to query the assembly manifest data, determine available types for reference, and view metadata included with that block of application code.

The Assembly.CreateInstance method supports dynamic invocation. You can use it to create a type reference based on the assembly. Because assemblies can contain numerous types, the Assembly class needs to support a method that returns a System.Type object for a specified class. It does that through the GetType method as shown the following code excerpt:

      // C# code      object oClass;       Type tType;      string strFileName;      string strClass;         Assembly asm = Assembly.LoadFrom(strFileName);       oClass = asm.CreateInstance(strClass);      tType = asm.GetType(strClass); 

The preceding code fragment shows how to use an Assembly object to load an assembly using the overloaded LoadFrom method, create an instance of a type reference using the assembly, and then create a System.Type object that represents the type reference by using the GetType method. Finally, you can use the Type object to invoke class members dynamically, using the overloaded InvokeMember method.

      // C# code      object[] oArguments = new object[0];          object oReturn = tType.InvokeMember("YourMethod",         BindingFlags.Default |          BindingFlags.InvokeMethod,         null, oClass, oArguments); 

The preceding fragment demonstrates invoking the YourMethod member of the assembly using the Type instance obtained from the previous example. Note that the array oArguments must contain any input parameters required by the method; in this example oArguments is an array with 0 elements. By using the Assembly object and the Type object as shown in the examples you can load an assembly at runtime, create a reference to one of the assembly types, and then dynamically invoke one of the type methods.

The JScript scripting language, based on a Microsoft implementation of the ECMA 262 language, has been overhauled and improved to support integration with the .NET Framework. The improvements include support for compiled code, type and type less variables, cross-language integration, and access to all of the .NET Framework classes and resources. In addition, there are enhanced performance features supporting faster script execution that can be used in conjunction with ASP.NET. All of these enhancements are geared towards providing a more flexible and robust environment for developing high performance applications with the .NET Framework while leveraging scripting technologies.

Here’s how to create and compile a simple class. First define a class in JScript.NET with a simple member function that returns a string, for example:

      // Jscript.NET code      class MyClass       {         function GetString() : string         {            return "MyString";         }      } 

Next, compile the class into a .NET assembly. You can use JScript compiler jsc.exe to compile the code using the command line. For the example class, you would write:

      jsc.exe /target:library MyClass.js 

The preceding command creates a file named MyClass.dll, which you can then reference just like any other .NET assembly. Precompiled script code provides a huge performance advantage over traditional script interpretation, and in addition, you can interoperate with the JScript.NET classes from any other .NET language.

Now that you’ve seen a bit of Jscript.NET, here’s an example application that performs a basic math calculation known as a factorial. The factorial of a number n is defined as n!, where n is an integer greater than 1, or more completely, n * (n-1)!. So for the number 3, 3! is equal to 3 * 2!, which is equal to 3 * 2 * 1, or 6. The point of this example is to demonstrate that you can develop applications that build unique scripts based on user input or other variable factors, and then compile and execute the code dynamically. For factorials, this capability is important because a standard recursive algorithm to perform the calculation degrades substantially as the number n becomes large; this example demonstrates a practical way to improve the performance of the factorial calculation for large number.

To begin the example, create a new Windows Forms application in C#. Add two text box controls (txtNumber and txtResult) and a command button named btnCompute to the form. The txtNumber TextBox will hold the factorial calculation and the txtResult TextBox will display the result. The btnCompute button will initiate the process to create the JScript.NET class code, compile it, and perform the factorial computation. Your form should look similar to Figure 1.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles:

©2023 Copyright DevX - All Rights Reserved. Registration or use of this site constitutes acceptance of our Terms of Service and Privacy Policy.

Sitemap