Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I emit code and inject it into a loaded assembly?

I've built some Types dynamically using System.CodeDom.CodeCompileUnit, want to compile those into IL code in memory, and inject that IL code into an assembly loaded in memory - there is no need to save any of this to disk. Maybe my stated plan is wrong. Open to other suggestions about how to get that CodeCompileUnit instance to the said destination.

like image 692
John K Avatar asked Nov 15 '09 02:11

John K


3 Answers

You can inject code into an existing (already loaded) assembly using ICorDebug interfaces. Edit and Continue does it.

Compute your delta bytes and call ICorDebugModule2::ApplyChanges. See the MDbg sample code for more details.

Once upon a time we used ICorDebugModule::GetEditAndContinueSnapshot and kin, but these are now deprecated.

Update If you don't care about injecting code into an already-loaded assembly, just using Reflection.Emit to create a new assembly is more efficient and a lot easier.

like image 148
Ray Burns Avatar answered Nov 15 '22 18:11

Ray Burns


You can also use System.Reflection.Emit namespace and create a dynamic, in-memory assembly.

Alternative is to use CodeDom to generate & compile code, then call into it.

XMLSerialization() does the latter.

like image 29
feroze Avatar answered Nov 15 '22 19:11

feroze


You can use Mono.Cecil to manipulate IL. It's a powerfull tool, though it somehow lacks documentation.

like image 37
Bolek Tekielski Avatar answered Nov 15 '22 19:11

Bolek Tekielski