I recently bought Ayende's book Building DSLs in Boo (buy it, read it, it's awesome) but I'm coming up against an implementation problem and I want to see what the generated code looks like. I would normally use reflector to look at the code but in this case the assemblies are dynamic and only in memory. Is there a way to save dynamic assemblies to disk so that I can reflect them?
EDIT / My Answer:
Wow, it took awhile to come back to this one. Unfortunately I left an important bit out from the original question.
Important Bit: I'm using Ayende's RhinoDSL library as he recommends in the book. I have access to the boo compiler in my subclass of DslEngine which looks like this:
public class JobEngine : DslEngine
{
protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls)
{
pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz"));
}
}
To change the least and get what I wanted I needed to add one line...
public class JobEngine : DslEngine
{
protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls)
{
compiler.Parameters.GenerateInMemory = false; // <--- This one.
pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz"));
}
}
This caused the compiler to output the assembly to my ~\LocalSettings\Temp directory and then I could then reflect it. It's important to note that making that change caused the rest of the program to break (RhinoDSL could no longer find the assemblies in memory because I output them to disk), so this is only useful as a debugging tool.
Look up where BooCompiler is instantiated, change the pipeline from CompileToMemory to CompileToFile
Yes, the AssemblyBuilder
class has a Save
method for this purpose. You need to use the appropriate mode for this, which is most likely RunAndSave
:
AssemblyBuilder builder =
AppDomain.CurrentDomain.DefineDynamicAssembly(
name, AssemblyBuilderAccess.RunAndSave);
// build assembly
builder.Save(path);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With