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


Dynamically Executing Code in .NET : Page 3

Dynamic code execution is a powerful feature that allows applications to be extended with code that is not compiled into the application. Users can customize applications and developers can dynamically update code easily. Learn what it takes to execute code dynamically with the .NET Framework and create a class that simplifies these tasks by wrapping the details of the process in an easy-to-use interface that requires only a few lines of code.

Making Life Easier with wwScripting
There's a lot of power in all of that code—it shows how much flexibility there is in the .NET Framework, but you certainly wouldn't want to put all of that code into your application each time you need to execute code dynamically. It's reasonably easy to abstract all of this code into a class. You can find the code in the wwScript.cs source file and in the Westwind.Tools.Scripting namespace with the wwScripting class.

The class provides the following features:

  • Transparent execution of C# and Visual Basic code
  • Execution in the current AppDomain or via external AppDomains for shutdowns
  • Error handling
  • High level and low level methods
With the class running dynamic code gets a bit easier as shown in Listing 5.

If you want to load the code into a different AppDomain call the CreateAppDomain("Name") method before the ExecuteCode() method call.

The class also includes several methods for executing code. For example, ExecuteMethod() allows you to provide a full method including the signature defining parameters and return values. This makes it possible to create properly typed parameters and return values. For example, take a code snippet like this:
   public string Test(string lcName, int x)
      string cHello;
      cHello = lcName;
      MessageBox.Show(cHello,"Compiler Demo");
      return DateTime.Now.ToString();
You can then run with this code:
   string lcResult = (string)
   "Test","rick strahl",x);
Notice that you can access the parameters directly by name in the dynamic code snippet. It's a little cleaner if you pass parameter and return values this way. You can also pass multiple methods as a string:
   public string Test(string lcName, int x)
      string cHello;
      cHello = lcName;
      MessageBox.Show(cHello,"Compiler Demo");
      return DateTime.Now.ToString();
   public string Test2(string lcName, int x)
      return Test(lcName,x);
You can then call the two methods like this:
   string lcResult = (string) loScript.ExecuteMethod(
      lcCode,"Test","rick strahl",(int) x);
   lcResult =  (string)
      "Test2","rick strahl",(int) x);
Note that making the second call is rather more efficient because the object already exists and is loaded. No recompilation or regeneration occurs on this second call.

CallMethod() is one of the lower level methods of the class. With it you can perform each step of the compile process individually. A number of other low level methods are (see Table 1 and Table 2).

Table 1: Low-level methods of the wwScripting object.

Low Level Method




Compiles an assembly and holds an internal pointer to the assembly object (only if locally loaded—AppDomains are handled from disk).

Source code


Creates an instance of the compiled code either in the local or a remote AppDomain. Sets the oObjRef property with the reference to the object or Interface.

Uses internal references to the Assembly or the name of the DLL file to load into an AppDomain.


Executes a method by name using the oObjRef pointer. Knows about local or remote AppDomain.


The method to call.

A variable list of parameters from 0 to n.


Creates an AppDomain and forces CreateInstance and CallMethod to use that domain to load and execute code in.


Name of the domain


Cleans up and releases references.


Table 2: Low-level properties of the wwScripting object.




Error flag that should be checked after making calls before using any results.


Contains error information either after compiling or running code.


Determines whether the code that is finally compiled is saved. Full assembly source code.


Set before compilation if lSaveSourceCode is true.


After a successful method execution (or after calling CreateInstance) this property contains an instance of the dynamic object.


Name of the namespace that the code is generated into. This is used to generate the assembly and then used again when the class is instantiated to reference the type.


Same as cAssemblyNamespace


Determines if certain assemblies and namespaces are loaded by default. Loads System, System.IO, System.Reflection.

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