C#中的自定义属性

时间:2009-09-15 20:39:10

标签: c# attributes custom-attributes

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

[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;
    }
}

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

2 个答案:

答案 0 :(得分: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页面)

答案 1 :(得分:0)

这可能超出你的需要,但......

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

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