Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

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.


advertisement
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) loScript.ExecuteMethod(lcCode, "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) loScript.CallMethod(loScript.oObjRef, "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

Function

Parameters

CompileAssembly

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

lcSource
Source code

CreateInstance

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.

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

CallMethod

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

lcMethod

The method to call.

Parameters()
A variable list of parameters from 0 to n.

CreateAppDomain

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

lcAppDomainName

Name of the domain

Dispose

Cleans up and releases references.

None



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

Property

Function

bError

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

cErrorMsg

Contains error information either after compiling or running code.

lSaveSourceCode

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

cSourceCode

Set before compilation if lSaveSourceCode is true.

oObjRef

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

cAssemblyNamespace

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.

cClassname

Same as cAssemblyNamespace

lDefaultAssemblies

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




Comment and Contribute

 

 

 

 

 


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

 

 

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