我最近买了阿扬德的书 在Boo中建造DSL (购买,阅读,很棒),但是我要面对实现问题,我想看看生成的代码的外观。我通常会使用反射器来查看代码,但是在这种情况下,组件是动态的,并且仅在内存中。有没有办法将动态组件保存到磁盘上,以便我可以反映它们?

编辑 /我的答案:

哇,花了一段时间才回到这个。不幸的是,我从最初的问题中留下了重要的意义。

重要点:我正在使用 Ayende的Rhinodsl库 正如他在书中推荐的那样。我可以访问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无法在内存中找到组件,因为我将它们输出到磁盘上),因此这仅作为调试工具有用。

有帮助吗?

解决方案

查找BoocOcompiler实例化的位置,将管道从 汇编汇编

其他提示

是的 AssemblyBuilder 班级有一个 Save 为此目的。您需要为此使用适当的模式,这很可能是 RunAndSave:

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

如果您可以在运行时获得组件。

IE

Assembly assembly = typeof(YourDynamicType).Assembly;

然后,您可以将此组件投入到汇编构建器中,并调用保存方法。

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

可能有一种更简单的方法可以做到这一点,但是如果您不介意使用WindBG,则可以从内存中保存任何已加载的托管组件(WindBG使用术语模块,但也适用于托管组件)。

使用 !savemodule 带有大会地址的命令。如果您没有地址,请使用 lm vm 带有模块名称的命令。之后,您将获得常规的DLL组件,可以在反射器中检查。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top