Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

DynamicMethod from C# code?


:P
On this page:

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.

Posted in .NET  

The Voices of Reason


 

Wilco Bauwer
May 14, 2007

# re: DynamicMethod from C# code?

Can you give a slightly more realistic example? Specifically I'd like to know if you really just want to be able to compile an arbitrary string. If so, I don't think there's much you can do besides writing your own compiler that does this and/or use the DLR's hosting APIs. The hosting APIs should let you quickly run some Python (/Ruby/JS/...) code much like what you described.

An alternative *may* be expression trees in C# 3.0. You can construct an expression tree and compile it on the fly. Under the hood it'll use LCG (=DynamicMethod). Once you have given a more realistic example, I can maybe illustrate how expression trees can be used to solve your problem (if they can).

Rick Strahl
May 14, 2007

# re: DynamicMethod from C# code?

The scenario I've used this with is dynamic validation rules. The rules are stored in metadata (as part of application in a database) and contains small code snippets that are user configurable without compiling the code. So the code is usually a few logical expressions that return true or false, but it can also be a few lines of code to arrive at the boolean result. At this point I use the compilation method of code above by basically running through all of the rules and creating a class out of them and then invoking the class. It works, but there's all sorts of stuff that needs to happen to make this work correctly including the overhead of having to compile everything up front setting up an AppDomain etc. etc. It'd be a heck of a lot easier to just be able to feed that block of code directly, get a method pointer and fire it off AND have it garbage collected after you're done.

I have a solution to the issue as it is (with the pre-compiled class code that I generate at runtime), but I would really like a more generic solution. If there was a more universal way to execute arbitrary code (permissions allowing) there are a lot of interesting things that you could.

It just seems to me if we have the logic there at the low, low level to create these dynamic methods, why not kick it up a notch and make it more accessible at the higher level - it opens up a score of opportunities for dynamic scenarios.

Wilco Bauwer
May 14, 2007

# re: DynamicMethod from C# code?

I see. Yeah, it'd be neat to have something like that. No idea how much of the codedom providers could be reused to leverage this though. I suspect technically it'd be non trivial, considering some syntactic sugar in method bodies actually require generating code outside of the method, just to name one of the simpler problems...

Considering DynamicMethod is limited to methods, how advanced would you need this to be? I suspect having some C#-based expression language would actually end up being very similar to what you could already achieve using one of the DLR-based languages, such as JScript... It may add a little overhead, but still, it's probably the most practical and rich option.

Nick Parker
May 14, 2007

# re: DynamicMethod from C# code?

As Wilco mentioned, you could possibly use the DLR hosting infrastructure, I have a simple contrived example here:

http://www.developernotes.com/archive/2007/05/01/DLR-Hosting-Services.aspx

Rick Strahl
May 14, 2007

# re: DynamicMethod from C# code?

Wilco, I think you can do this sort of thing with JScript.NET already as well even without using the DLR.

http://west-wind.com/weblog/posts/10688.aspx

This would possibly an option, although I suspect the preferred language for scripting would be either C# or VB.

While the dynamic languages are Ok for this, why not extend this to the 'classic' .NET languages? It seems to me with a Dynamic method we're bypassing some of the nasty issues of name munging etc. in the compilation process and dealing mostly with the process of generating the core IL that's used. I mean if we can create IL code manually there ought to be a way for the compiler to generate this for us from string (or stream) inputs.

It's an intersting topic - something I've been thinking about ever since I started with .NET.

Rick Strahl's Web Log
June 23, 2007

# Rick Strahl's Web Log


Stefan Züger
July 23, 2007

# re: DynamicMethod from C# code?

I'm also looking for DynamicMethod from C# code.

I found on Haibo Luo's weblog the entry Turn MethodInfo to DynamicMethod (http://blogs.msdn.com/haibo_luo/archive/2006/11/07/turn-methodinfo-to-dynamicmethod.aspx).

Based on this appraoch the application .Net Expression Evaluator using DynamicMethod is done by Wilson Drew (http://www.codeproject.com/csharp/ExpressionEval.asp)

>-> | >-> (FTG)
October 24, 2007

# re: DynamicMethod from C# code?

It seems you can create a MethodInfo object using CodeDOM, and just create its assembly in memory. Afterward, you can get the MethodInfo from the assembly and dump the rest. I tried the following code to do this. I am not sure how to tell if the assembly is actually loaded when it is created, but it would appear not because I can make repeated calls to the create method, which I would expect to crash if the old assembly were still loaded. I would think it would crash because the create method would be trying to make another method of the same signature in the same place.

private MethodInfo CreateDynamicMethod(string methodCode)
{
CSharpCodeProvider codeProvider = new CSharpCodeProvider();

CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.OutputAssembly = "TestAssembly";
parameters.GenerateInMemory = true;

CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters,
ClassString.Replace("TestMethod", codeTextBox.Text));

if (results.Errors.Count > 0)
{
throw new Exception("Compiler Errors");
}
else
{
compileTextLabel.Text = "Succeeded";
return results.CompiledAssembly.GetTypes()[0].GetMethods()[0];
}
}

private static string ClassString = @"
using System.Text;
namespace TestNameSpace
{
public class TestClass
{
public static TestMethod
}
}
";

Eugene Ciloci
November 07, 2007

# re: DynamicMethod from C# code?

Have a look at the Flee (Fast Lightweight Expression Evaluator) project on codeplex (http://www.codeplex.com/flee). It is built around a custom parser and compiler that takes care of emitting the IL for a given expression to a DynamicMethod.

Brad
February 13, 2008

# re: DynamicMethod from C# code?

I'm trying to build dynamic user-scripting into my C# app, and it SEEMS like it shouldn't be this tough.

I want a user to be able to write a simple C# script and save it in an XML file. Here is a simple example of what a user might create:
.............
<msxsl:script language="C#" implements-prefix="msxsl">
<![CDATA[
public Double Weight()
{
switch (MyCSharpClass.DataField("fieldname")
{
Case "S1":
return 10;
break;
Case "M":
return 11;
break;
Default:
return 0;
break;
}
}

]]>
.....................

Then I want my C# host app to read the xml file and execute that user code, and retrieve the Double value that the Weight() method returns. Everyone who has replied here seems to know their way around this stuff, but honestly I can't tell if these posts are addressing this situation or not? Can anyone help me?

Thanks,
Brad

Paul Kimmel
September 24, 2008

# re: DynamicMethod from C# code?

I really wish that there was a facility in .NET that allowed you do something like this:

I think there is netasm does actual code injection, of course its not easy.

Rick Strahl
September 24, 2008

# re: DynamicMethod from C# code?

@Paul - yes sure you can do it with Reflection emit, but this is not a generic solution. The most common requirement for dynamic code execution tends to be arbitrary user specified code usually for plug-in customization type or scripting applications.

This is a pain in the ass to do with .NET and it'd be nice if there was an easy way to do this.

I've written some code a long time ago that does this by compiling snippets on the fly in new classes etc. IT works but it's problematic too because once classes load they can't unload unless the AppDomain gets unloaded.

Johann
March 23, 2009

# re: DynamicMethod from C# code?

Hi Rick.

Did you manage to find a solution to this at all?

I'm looking at doing something exactly like what you have been trying to do: executing dynamic validations on the fly without having to recompile the whole caboodle.

I.e.

bool ValidationResult = DoDynamicValidation("(a > b) and b = \"blah\"");


and I want that to return a true if the validation passes, and a false if it doesn't.

I could even alter that condition to put the actual values in, like this:

bool ValidationResult = DoDynamicValidation("(1 > 2) and \"Blah\" = \"blah\"");


The only other alternative I see to this, is doing it in SQL, but that would mean database overhead. Not good.

So, have you found any easy solutions or are you still looking?

Thanks,
Johann.

Rick Strahl
March 23, 2009

# re: DynamicMethod from C# code?

@Johann - there's another way using Expression Trees which I talked about here (which links to another post by Nate Kothari):

http://www.west-wind.com/Weblog/posts/653034.aspx

But this doesn't address totally generic code either only invocation or preexisting methods.

Any dynamic code in .NET needs to be compiled so whether you have to do it, or the compiler behind the scenes somewhere that code gets compiled into an assembly.

With validation rules what I would probably do is store them in the database as part of a rules table, then create a single class (or set of classes) and then compile all of them at once when the application starts - preferrably on a separate thread to mitigate the startup cost. That way you end up compiling just once instead of for every little snippet. I've helped a few folks set up this scenario and it works well enough although it is a bit of work still.

Ziad Elmalki
January 08, 2010

# re: DynamicMethod from C# code?

I just finished up a .NET 2.0 project where they wanted to add a function/condition editor for a datagrid where users can create computed columns.

I found this example here and heavily modified it so it would work with my expression tree (since 2.0), added support for intellisense/autocomplete, etc. We parse the string, build the tree, and then create a dynamic method that represents the function/conditon the user created.

DynamicQuery: Code to create LINQ queries at run time.
http://code.msdn.microsoft.com/csharpsamples

Would love to share the code with you if you are interested :)

devang
January 02, 2012

# re: DynamicMethod from C# code?

Hi Rick,

I am thankful to you for posting this as after lots ofresearch for solution to this problem, could not find any other alternatives that you already mentioned in this post. All other methods like Reflection.emit and ironPython options are very low level programming. ExpressionTree option is also very limiting in terms of coverage. Please keep me posted if you find any solution to this problem in future.

Thanks,
Devang

Punit
September 02, 2012

# re: DynamicMethod from C# code?

You can try out
http://codeinject.codeplex.com for injecting your C# or VB.NET code into assemblies

FM
September 03, 2015

# re: DynamicMethod from C# code?


Dale
September 28, 2016

# re: DynamicMethod from C# code?

If you're using .NET 4.6, you can use Microsoft.CodeAnalysis.CSharp.Scripting. Here's some samples: https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024