2010-09-09 26 views
6

我在c#中反思有点新。我试图生成一个所有控制器的列表,以测试它们是否用特定的actionfilter装饰。在编写单元测试时,你如何访问被测试的程序集?反映控制器列表

这似乎并不工作:

var myAssembly = System.Reflection.Assembly.GetExecutingAssembly(); 

回答

4

如果你知道在你的主组件中的类型,你可以使用:

private IEnumerable<Type> GetControllers() 
    { 
     return from t in typeof(MyType).Assembly.GetTypes() 
       where t.IsAbstract == false 
       where typeof(Controller).IsAssignableFrom(t) 
       where t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) 
       select t; 
    } 

更换MyType与已知类型。

我在基类使用此与this.GetType()代替typeof(MyType),使我可以引用其中的derrived类型被定义组装。

+0

谢谢约翰。一个问题:“typeof(Controller).IsAssignableFrom(t)”是否足以确认它是控制器类型?我也对Linq有点新,顺便说一句:) – morganpdx 2010-09-09 21:28:16

+0

是的,这应该是足够的。我只是看了MVC的源代码,看起来他们并不关心它是否EndWith(“Controller”)',所以你可能会拿出那部分。 – 2010-09-09 21:31:30

0

您在编写测试时会知道程序集的名称。使用Assembly.ReflectionOnlyLoad()是此场景的适当选择。

作为一种替代方案,您可以从程序集中任何已知类型的Assembly属性中进行绘制。

0

Assembly.GetAssemblyByName()可能是查找非您的组件的票。它将查看应用程序的程序集绑定,然后查看当前应用程序目录,然后查看GAC。您也可以通过调用GetType().Assembly来获得给定对象实例或静态引用类型的Assembly类。

在此Assembly类中,您可以使用GetExportedTypes()遍历Type对象中包含的类型。这将只返回公共类型;那些你可以访问的,如果你静态引用程序集。你可以通过任何你可以反思分析的东西来过滤这些;名称,父类型,成员名称,装饰类或任何成员的属性等。