【发布时间】:2017-04-06 11:18:45
【问题描述】:
我正在努力在我的应用程序中创建一个特定接口的所有实现的列表,我试图通过 T4 模板中的反射来实现这一点,并使用它来生成 C#。
我有一些看起来像这样的代码:
<#@ 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 的类型。
从我看文档的情况来看,这可能是因为 IAction 接口是在 Project1 中定义的,GetTypes() 可能存在与调用时加载的程序集相关的问题。但是,据我所知,实际调用运行顺利——我没有看到ReflectionTypeLoadException 被抛出——它只是找不到那些接口实现。如果我列出 types2 集合中返回的所有内容的名称,则列表中不存在这些类名。
我需要做什么才能在我的第二个程序集中找到IAction 接口的实现?
【问题讨论】:
-
当然,project2 可能不是使用对 Project1.Interfaces 的引用构建的,而是使用自己的 IAction 接口定义。行不通,.NET 中的类型标识不仅仅是命名空间+类型名,它还包括定义它的程序集。
-
Project2 包含对 Project1 dll 的引用,并且 Project1.Interfaces 在相关类中被引用。我不太了解这里的内部结构——Project2 会以某种方式在内部创建一个不同的版本或 IAction 副本来掩盖 Project1 的原始版本吗?
-
是的,这并非不可能。我们对包含 IAction 的 DLL 一无所知。也许你有不止一个副本。使用 Fuslogvw.exe 进行故障排除,记录所有绑定,以便您可以看到它正在加载。
标签: c# reflection t4