当我创建这样的自定义属性来定义类上的一些元数据时,我经常构建一个小例程,它使用反射扫描程序集的所有类。
在我当前的项目中,我使用的是IoC框架(其他故事),而不是在自定义配置文件中配置它,我自己构建了一个 ComponentAttribute,它定义了一个类所属的接口。(从鸟瞰的角度来看:我稍后向 IoC 框架询问接口,它知道如何实例化实现该接口的类以及它们如何组合在一起)
要配置该 IoC 框架,我需要调用某个类的成员并告诉它存在哪个类到接口映射。
ioc.ConfigureMapping(classType, interfaceType)
为了找到所有这些映射,我在我的一个助手类中使用了以下两种方法
internal static void Configure(IoCContainer ioc, Assembly assembly)
{
foreach (var type in assembly.GetTypes())
AddToIoCIfHasComponentAttribute(type, ioc);
}
internal static void AddToIoCIfHasComponentAttribute(Type type, IoC ioc)
{
foreach (ComponentAttribute att in type.GetCustomAttributes(typeof(ComponentAttribute), false))
{
ioc.ConfigureMapping(attribute.InterfaceType, type);
}
}
我在这里所做的是在第一种方法中枚举所有程序集的类型,而不是在第二种方法中评估属性。
回到你的问题:
使用类似的方法,您可以找到所有标记的类并将它们与您在属性中定义的所有数据(页面路径等)一起记录在一个容器(ArrayList 或类似)中。
更新(回复评论)
在 Visual Studio 中构建程序时,通常会有一个或多个项目。对于每个项目,您将获得一个不同的程序集(.dll 或 .exe 文件)。上面的代码将检查一个程序集中的所有类。这样看来,程序集是收集的 .cs 文件的集合。因此,您要搜索程序集,而不是 .cs 文件的目录(它们是源代码,不是正在运行的应用程序的一部分。)
那么可能缺少什么:当您想要搜索类时,如何从代码中访问程序集?您只需参加您知道的任何课程(即在您的其他课程所在的程序集/项目中)并通过调用获取它所在的程序集
var assembly = typeof(MyDummyClass).Assembly;
然后你会调用你从上面的代码派生的东西
AnalyzeClasses(assembly)
和 AnalyzeClasses 看起来像
internal static void AnalyzeClasses(Assembly assembly)
{
foreach (var type in assembly.GetTypes())
AnalzyeSingleClass(type);
}
internal static void AnalzyeSingleClass(Type type)
{
foreach (MyCustomAttribute att in type.GetCustomAttributes(typeof(MyCustomAttribute), false))
{
Console.WriteLine("Found MyCustomAttribute with property {0} on class {1}",
att.MyCustomAttributeProperty,
type);
}
}
而且您只需在运行应用程序代码之前调用所有这些,例如在 main() 的顶部(用于应用程序),或者如果在高级中很难调用,您也可以在需要收集的数据时按需调用它。(例如来自 ASP.NET 页面)