2

我的页面有一个自定义属性,如下所示:

[PageDefinition("My page", "~/Parts/MyPage.aspx")]

我的 PageDefinition 看起来像这样,其中为 Title、Url、IsPage 和 IsUserControl 设置了 AttributeItemDefinitions

public class PageDefinition : AttributeItemDefinitions
{
    public PageDefinition(string title, string url)
        : this()
    {
        Title = title;
        Url = Url;
    }

    public PageDefinition()
    {
        IsPage = true;
        IsUserControl = false;
    }
}

但我找不到任何好方法将具有该属性的所有页面添加到占位符,其中所有链接都应与标题和 url 一起列出。你有什么好主意吗?谢谢你的帮助。

4

2 回答 2

1

当我创建这样的自定义属性来定义类上的一些元数据时,我经常构建一个小例程,它使用反射扫描程序集的所有类。

在我当前的项目中,我使用的是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 页面)

于 2009-09-15T20:43:31.937 回答
0

它可能比你需要的多,但是......

我在我的项目中一直遇到这种模式,所以我实现了一个类型加载器,它可以提供用户定义的委托以进行类型搜索匹配。

http://www.codeproject.com/KB/architecture/RuntimeTypeLoader.aspx

于 2009-09-15T20:52:00.167 回答