2017-04-06 41 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的副本来解决此问题(通过选择哪个输出文件夹),在这一点上,我的集合中出现了所有界面的实现。

希望这可以帮助任何遇到同样问题的人,但如果能得到更详细的解答导致问题的确切过程的答案将是非常好的。

相关问题