【问题标题】:Custom attributes in C#C# 中的自定义属性
【发布时间】:2009-09-15 20:39:09
【问题描述】:

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

[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 一起列出。你有什么好主意吗?感谢您的帮助。

【问题讨论】:

    标签: c# attributes custom-attributes


    【解决方案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 页面)

    【讨论】:

    • 好吧,我没有找到使用它的好方法。但是我不能只搜索一个里面有类的文件夹吗? “myclass.cs”类的属性在哪里?
    • Frozzare,我已经编辑了我的答案作为对您评论的回应。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      • 1970-01-01
      • 1970-01-01
      • 2020-07-02
      • 2020-12-19
      相关资源
      最近更新 更多