2010-01-13 62 views
9

我最近買Ayende的書Building DSLs in Boo(買它,閱讀它,它的真棒),但我來面對實施方面的問題,我想看到生成的代碼是什麼樣子。我通常會使用反射器來查看代碼,但在這種情況下,程序集是動態的,只能在內存中使用。有沒有辦法將動態程序集保存到磁盤,以便我可以反映它們?是否可以將動態程序集保存到磁盤?

編輯/我的回答

哇,這了一段時間回來這一個。不幸的是,我留下了一些重要的問題。

重要的一點:我使用Ayende's RhinoDSL library,他在書中建議。我有機會獲得噓編譯器在我DslEngine的子類,如下所示:

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無法再在內存中找到程序集,因爲我將它們輸出到磁盤),所以這隻作爲調試工具很有用。

+0

使用對象的XML序列化改變?!。 – serhio 2010-01-13 16:29:03

+0

您是否通過CodeDom創建該組件? – 2010-01-13 16:30:46

回答

4

查一查其中BooCompiler被實例化,管道從CompileToMemoryCompileToFile

+0

這就是最終讓我得到了我需要的答案的原因1接受你的先生。 – 2010-05-18 20:15:10

4

是的,AssemblyBuilder類具有用於此目的的Save方法。您需要使用此相應的模式,這是最有可能RunAndSave

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

這個程序集已經由Boo Compiler爲我編譯。所以我沒有權限訪問構建器...... – 2010-01-13 16:42:35

+0

這是一個動態組合,如果它沒有被保存並從磁盤加載,在這種情況下應該轉換爲'AssemblyBuilder'。 – 2010-01-13 16:46:03

+1

@大衛L:嗯...當我投命中保存方法我得到一個InvalidOperationException說,它被保存。 – 2010-01-13 17:01:52

0

如果你可以在運行時得到大會。

Assembly assembly = typeof(YourDynamicType).Assembly; 

然後,您可以施放此組裝成AssemblyBuilder和調用Save方法。

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

其實這個演員陣容很有效,但是當我運行保存方法時,它死了,說組件已經被保存了...... – 2010-01-13 17:02:57

0

有可能是做一個簡單的方法,但如果你不介意使用WinDbg中,你可以保存任何加載託管程序集從內存(WinDbg中使用術語模塊,但它工作在管理組件以及)。

使用!savemodule命令與組件的地址。如果您沒有地址,請使用lm vm命令和模塊名稱。之後,您將獲得一個常規的DLL程序集,您可以在Reflector中進行檢查。

當然,你也可以只是看在內存中的IL代碼。