是否可以将动态组件保存到磁盘上?
-
20-09-2019 - |
题
我最近买了阿扬德的书 在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无法在内存中找到组件,因为我将它们输出到磁盘上),因此这仅作为调试工具有用。
其他提示
是的 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代码。
不隶属于 StackOverflow