是否可以将动态程序集保存到磁盘?

时间:2010-01-13 16:24:56

标签: .net dynamic assemblies boo

我最近买了Ayende的书Building DSLs in Boo(买它,读它,它真棒)但是我遇到了一个实现问题,我想知道生成的代码是什么样的。我通常会使用反射器来查看代码,但在这种情况下,程序集是动态的,只在内存中。有没有办法将动态程序集保存到磁盘,以便我可以反映它们?

编辑/我的回答

哇,花了一段时间才回到这个。不幸的是,我从原来的问题中留下了一点重要的内容。

重要位:我正在书中推荐使用Ayende's RhinoDSL library。我可以访问我的DslEngine子类中的boo编译器,如下所示:

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"));
    }
}

要改变最少并得到我想要的东西,我需要添加一行......

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"));
    }
}

这导致编译器将程序集输出到我的〜\ LocalSettings \ Temp目录,然后我可以反映它。重要的是要注意,进行该更改会导致程序的其余部分中断(RhinoDSL无法再在内存中找到程序集,因为我将它们输出到磁盘),因此这仅用作调试工具。

4 个答案:

答案 0 :(得分:5)

查看BooCompiler实例化的位置,将管道从CompileToMemory更改为CompileToFile

答案 1 :(得分:4)

是的,AssemblyBuilder类为此目的使用了Save方法。您需要使用适当的模式,这很可能是RunAndSave

AssemblyBuilder builder =
    AppDomain.CurrentDomain.DefineDynamicAssembly(
        name, AssemblyBuilderAccess.RunAndSave);
// build assembly
builder.Save(path);

答案 2 :(得分:0)

如果可以在运行时获得程序集。

Assembly assembly = typeof(YourDynamicType).Assembly;

然后,您可以将此程序集转换为AssemblyBuilder并调用Save方法。

AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly;
assemblyBuilder.Save(yourPath);

答案 3 :(得分:0)

可能有一种更简单的方法,但如果您不介意使用WinDbg,则可以从内存中保存任何已加载的托管程序集(WinDbg使用术语模块,但它也适用于托管程序集)。

!savemodule命令与程序集的地址一起使用。如果您没有地址,请使用带有模块名称的lm vm命令。接下来,您将获得一个常规的DLL程序集,您可以在Reflector中进行检查。

当然,您也可以只查看内存中的IL代码。