2017-04-06 72 views
0

我正在創建我的應用程序中特定接口的所有實現的列表,我試圖通過T4 Template中的反射來完成此操作,用它來生成C#。Assembly.GetTypes()不會返回實現在其他地方定義的接口的類型

我有一些代碼,看起來像這樣:

<#@ assembly name="$(SolutionDir)\..\Project2\bin\project1.dll" #> 
<#@ assembly name="$(SolutionDir)\..\Project2\bin\project2.dll" #> 
<#@ import namespace="Project1.Interfaces" #> 
<# 
    string assemblyPath1 = this.Host.ResolvePath("..\\Project2\\bin\\project1.dll"); 
    string assemblyPath2 = this.Host.ResolvePath("..\\Project2\\bin\\project2.dll"); 
    var type = typeof(Project1.Interfaces.IAction); 
    var types1 = Assembly.LoadFrom(assemblyPath1).GetTypes() 
       .Where(p => type.IsAssignableFrom(p) && p.IsClass).ToList(); 
    var types2 = Assembly.LoadFrom(assemblyPath2).GetTypes() 
       .Where(p => type.IsAssignableFrom(p) && p.IsClass).ToList(); 
#> 

顯然,真實版做了很多,你可以假設,如果你不能看到import指令我在這裏省略它的簡潔和可讀性。但據我所知,這是問題出現的地方。該types1變量將包含一大堆的IAction實現的列表,但types2列表是空的,儘管我有我的面前Project2的右側開放的事實,它肯定包含實現IAction幾個公共類型。

從我可以告訴看文檔,這可能是因爲在Project1中定義了IAction接口,並且在調用時會加載與裝入程序相關的GetTypes()問題。但是,據我所知,實際的通話運行平穩 - 我沒有看到ReflectionTypeLoadException被拋出 - 它只是沒有找到那些接口實現。如果列出types2集合中返回的所有內容的名稱,則列表中將缺少這些類名稱。

我需要做什麼才能在我的第二個程序集中找到IAction接口的實現?

+0

當然,project2可能沒有建立對Project1.Interfaces的引用並使用它自己的IAction接口定義。無法工作,在.NET中輸入身份不僅僅是名稱空間+類型名稱,它還包含它在其中定義的程序集。 –

+0

Project2包含對Project1 dll和Project1.Interfaces在相關類中引用的引用。我對這裏的內部知識不太瞭解,Project2會不會在內部創建一個不同版本或IAction的副本,以掩蓋Project1的原始版本? – glenatron

+1

是的,這不是不可能的。我們不知道包含IAction的DLL。也許你有不止一個副本。使用Fuslogvw.exe進行故障排除,記錄所有綁定,以便您可以看到它已加載。 –

回答

0

在Hans Passant的評論之後,我確信我使用了屬於同一個依賴鏈的dll的副本,而不是使用來自不同來源的dll的副本來解決此問題(通過選擇哪個輸出文件夾),在這一點上,我的集合中出現了所有界面的實現。

希望這可以幫助任何遇到同樣問題的人,但如果能得到更詳細的解答導致問題的確切過程的答案將是非常好的。

相關問題