2010-04-10 79 views
4

我試圖在.Net中動態創建程序集。但是,我似乎無法弄清楚如何讓CodeBase屬性返回一個值。這裏有一個例子:無法從動態生成的程序集中訪問CodeBase

var assemblyName = new AssemblyName 
         { 
          Name = "Whatever", 
          CodeBase = Directory.GetCurrentDirectory() 
         }; 
var assemblyBuilder = AppDomain.CurrentDomain 
    .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); 
var moduleBuilder = assemblyBuilder.DefineDynamicModule("WhateverModule", "Whatever.dll"); 
var typeBuilder = moduleBuilder.DefineType("WhateverType", TypeAttributes.Public); 
var type = typeBuilder.CreateType(); 
assemblyBuilder.Save("Whatever.dll"); 
var codeBase = type.Assembly.CodeBase; // throws the below exception 

System.NotSupportedException was unhandled 
    Message=The invoked member is not supported in a dynamic assembly. 
    Source=mscorlib 
    StackTrace: 
     at System.Reflection.Emit.InternalAssemblyBuilder.get_CodeBase() 
     at Stupid.Program.Main(String[] args) in C:\Users\Walking Disaster\Documents\Visual Studio 10\Projects\Lingual.Proxy\Stupid\Program.cs:line 25 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 

任何人都可以看到我做錯了什麼?

說明:我試圖用一個在運行時生成測試方法的插件來擴展NUnit。它通過獲取一系列Action委託來完成此操作。不幸的是,Reflection已經深入到框架中了,所以我不得不爲每個Action委託放一個方法。當我僅使用NUnitTestMethod類時,這很好,但是當我使用NUnitTestFixture時,它失敗了,因爲它試圖從程序集中讀取CodeBase。我不想創建一個物理組件,但是這個項目卻是一個接一個的妥協。

回答

2

我認爲異常的原因是CodeBase在動態裝配上沒有意義。從MSDN:

按原規定

如果你重裝組裝也不會拋出異常的程序集的位置:

var assemblyName = new AssemblyName 
         { 
          Name = "Whatever", 
          CodeBase = Directory.GetCurrentDirectory() 
         }; 
var assemblyBuilder = AppDomain.CurrentDomain 
    .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); 
var moduleBuilder = assemblyBuilder.DefineDynamicModule(
    "WhateverModule", "Whatever.dll"); 
var typeBuilder = 
       moduleBuilder.DefineType("WhateverType", TypeAttributes.Public); 
var type = typeBuilder.CreateType(); 
assemblyBuilder.Save("Whatever.dll"); 

var assembly = Assembly.LoadFrom("Whatever.dll"); 
var codeBase = assembly.CodeBase; // this won't throw exception 
+0

我對此很害怕。我可能必須這樣做才能完成,然後深入研究NUnit,試圖限制它們嚴重依賴反射所造成的損害。 – 2010-04-10 23:24:54

1

是大會Location有效?你可以分叉NUnit,並使用它,而不是給你的參考被損壞:P

我花了幾個小時受到NUnit的'可擴展性'的故事,無法想象從來沒有選擇它在xUnit.net - 但我猜決定性的將是你有多少測試...

+1

我和你在一起。我不能相信NUnit選擇通過反射來獲取所有的測試元數據。不幸的是,這是針對現有的項目,我們已經有了7K + NUnit測試。我知道xUnit允許你運行NUnit測試,但是有一個抑制措施可以把它接近項目的完成。儘管如此,我正在考慮將我的工作移植到xUnit中,以用於下一個項目。 – 2010-04-11 02:20:24

+1

我想這不太合適,但是你看過RunWithNUnitAttribute [它允許你通過xunit runner運行NUnit測試]。沒有看到任何例子,但是你會驚訝於xunit中的Samples是乾淨的還是簡單的(下載示例並查找NUnitRunnerAcceptanceTests)? (是的,一個很長的鏡頭!) – 2010-04-12 08:23:57

相關問題