I'm experimenting with DynamicMethod in .NET 2.0 in light of all the good things that apparently have come of it especially in light of the recent release of the Dynamic Language Runtime on CodePlex. I haven't dug into that code (I suspect it won't be light reading <s>), but thought it sure would be nice to have a more dynamic execution mechanism that can take arbitrary code and execute it.
I would love to have the functionality to dynamically create a block of code and execute it as part of scripting engine I've written a long time ago. It works but it would be a heck of a lot nicer if the dynamic code I execute as part of these scripts didn't have to be compiled into separate classes.
DynamicMethod works with IL code generation and it's a pretty low level approach. You can find an example here
http://msdn2.microsoft.com/en-us/library/system.reflection.emit.dynamicmethod.aspx
There are countless more examples out there where this is demonstrated, but unless you're a compiler writer or doing other kinds of low level code-parsing, this is not really useful in dynamic execution of code in your own applications. After all if you have IL code, you're just taking another bit of static code and exchanging it for another a higher level bit of code.
I really wish that there was a facility in .NET that allowed you do something like this:
public delegate int delAdd(int Num1, int Num2);
public void ExecuteCode()
{
string MethodBody =
@"Num1 += 10;
Num2 += 10;
return Num1 * Num2;";
Type[] parameterTypes = { typeof(int),typeof(int) };
DynamicMethod dm = new DynamicMethod("MultiplySpecial",
typeof(int), parameterTypes,
this.GetType(),
MethodBody,
CodeDomProvider.CreateProvider("CSharp"));
delAdd AddMethod = dm.CreateDelegate(typeof(delAdd));
int Result = AddMethod(10, 20);
...
}
Wishful thinking I know. So, warning before you go on here <s> - I don't have a solution to this problem and I'm looking for some thoughts on this scenario.
There's a lot of talk about 'dynamic' code execution these days, but this fundamental ability to execute arbitrary code easily has really never been addressed in the core .NET languages. Since we have DynamicMethod in the first place, why not make it easier to actually take advantage of it? It seems to me all the tools to do this are already built into the CLR and compilers, but they're not exposed...
BTW, the issue here isn't the syntax, but as far as I can tell there's no built-in mechanism for turning arbitrary code snippets into IL or CodeCompileUnits.
Other ways
A long, long time ago I wrote about dynamic compilation and execution (oddly enough this was one of the first things I experimented with in .NET of all things - and it shows in that I hadn't gotten over my FoxPro coding convention - eeek) and in that document I basically take text based strings, wrap them up in proper module definition (ie. add namepace and class around it) and then compile the whole thing using appropriate VB or CSharp compiler. The resulting assembly can be executed in memory or stored to disk - and subsequently can be loaded into a separate AppDomain for unloading.
There are other ways to accomplish this of course and a more lightweight way is to use the CodeDom to generate the code in a language agnostic way so the compilation step can be skipped. You could also use even lower level IL to generate. Unfortunately, if you truly have dynamic code that is generated externally from your application that's not really an option as you need something that can parse the source code into IL in the first place.
All of that works, but it's a pretty heavy process and it also has to deal with one effect of the .NET runtime: Any assembly loaded into a given cannot be unloaded once it's been loaded. The only way to unload code is by unloading the hosting AppDomain, which although not difficult to do is not necessarily easy to manage if you need to generate lots of code on the fly.
DynamicMethod
So DynamicMethod seems to address some of these issues. Althogh I'm not 100% clear of all the benefits. The main feature as far as I can see it over other approaches is that dynamic methods are garbage collected because they don't generate a separate assembly. DynamicMethod performs what amounts to runtime code injection. Some of the other features - treating the code as a 'value' that can be passed around - can be pretty much accomplished with plain delegates or even more easily with Anonymous Methods. The only difference is that all that code truly is static vs the semi-dynamic nature of Dynamic Method.
DynamicMethod is basically a more lightweight implementation in that it doesn't require a full assembly, and that it is in essence a function pointer that is garbage collected. Unlike my compilation code I used before no distinct assembly is generated. Sounds great...
Looking at DynamicMethod in the MSDN docs it I found a decent example and a few others, but the problem is all of these deal with direct IL emission, which apparently is the only way to generate the dynamic method code. While that's all fine and dandy for compiler writers and other code parsing applications, how can we take advantage of this functionality more directly via code or strings of code that needs to dynamically run?
So really for me the big question that I haven't been able to solve is how do we go from a code snippet in CSharp (or VB) to tokenized IL that can be fed to DynamicMethod's ILGenerator?
That shouldn't be so hard, right? .NET conveniently includes code compilers for CSharp and VB (as well as other languages if they publish their compiler APIs) and it's relatively straight forward to use these compilers to compile whole source files/modules. This is the approach I used for my previous attempt at dynamic code execution.
Unfortunately the compiler only works for generating assemblies as far as I can tell. It can't compile just a method or a snippet of code. The CodeDomProvider interface supports a .Parse() method which should address this scenario, but unfortunately it's not implemented.
So, am I missing something here? (wouldn't be the first time) Given that the CSharp compilation classes don't expose partial compilation functionalty is there another way (short of manually creating the lexing code)? I ran into a few C# code parsers that do this here and here.
Other Posts you might also like