Attaching an existing method to a dynamic assembly

2019-06-14 19:41发布

问题:

I am new to the Reflection.Emit API and have generated a bare minimum assembly with an entry point that returns an exit code based on a few simple I/O checks. The reason for creating an external assembly is that a piece of code needs to run outside the current process space and will be transient itself. It will eventually be deleted by the creating app.

Having said that, the code to be generated is quite complex and I would rather avoid creating a separate project for a transient assembly. I don't know IL enough to use the ILGenerator for this complex a method.

I have also read this SO question about using existing methods to generate IL and it does not seem possible short of parsing IL. I don't know of a way to take an existing method, detach it from the current context and add it to the new dynamic type. If such a way exists, that would be an acceptable answer to this post.

My final though is to have the generated assembly reference the generating assembly as a library. even though both assemblies are WinForms apps, is there a downside to referencing them as a library?

回答1:

Finally solved it using Expression Trees instead of having to emit raw IL.

var queue = new Queue<Expression>();
var arguments = Expression.Parameter(typeof(string []), "args");

queue.Enqueue(Expression.Call(typeof(Console).GetMethod("WriteLine", new Type [] { })));

var block = Expression.Block(queue);
var lambda = Expression.Lambda<Func<string [], int>>(block, new ParameterExpression [] { arguments });

lambda.CompileToMethod(builderMethod);
// builderMethod is a MethodBuilder instance created earlier.

This is very powerful indeed and definitely suited for situations where micro-perf is not required using ILGenerator.