无法从GetCustomAttributes获取属性

时间:2012-07-16 18:53:57

标签: c# visual-studio-2010 reflection

在我的MiddleTier项目的解决方案中,我有Customer类,其中一个用Attribute1

定义
public class Customer2
{
    public string Name2 { get; set; }

    public int Age2 { get; set; }
}

[MyAttribute1]
public class Customer1
{
    [MyAttribute1(DefaultValue = "Must Enter Name")]
    public string Name { get; set; }

    [MyAttribute1(DefaultValue = "Must Enter Age")]
    public int Age { get; set; }
}

[AttributeUsage(AttributeTargets.All)]
public class MyAttribute1 : Attribute
{
    public string DefaultValue { get; set; }

}

在一个单独的项目中,我引用了MiddleTier DLL,我希望枚举此DLL中的所有类,并标识与Attribute1关联的Customer1类。

            Assembly assembly =  Assembly.LoadFrom(@"C:\myfolder\MiddleTier\bin\Debug\MiddleTier.dll");

            foreach (Type type in assembly.GetTypes())
            {

                var attribs = type.GetCustomAttributes(typeof(MyAttribute1), false); <--- problem
                if (attribs != null && attribs.Length > 0)
                {
....
                }
            }

没有通过GetCustomAttributes 调用获取任何属性。我究竟做错了什么?请帮忙。感谢

2 个答案:

答案 0 :(得分:8)

问题是您实际上是从两个不同的位置加载程序集两次。这会导致程序集被加载到两个不同的上下文中,这反过来会导致您的类型不兼容。当您尝试运行此代码时,可以轻松验证这一点(当然,您需要更改程序集的路径):

foreach (Type type in Assembly.LoadFrom(@"C:\ClassLibrary1.dll").GetTypes())
{
     MyAttribute1 attribute = type.GetCustomAttributes(false)
                                  .Cast<MyAttribute1>()
                                  .SingleOrDefault();
    if (attribute != null)
    {
       Console.WriteLine(type.Name);
    }

}

这将导致抛出以下异常:

  

[A] ClassLibrary1.MyAttribute1无法转换为   [B] ClassLibrary1.MyAttribute1。 A类源自'ClassLibrary1,   上下文中的Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'   位于'C:\ ClassLibrary1.dll'的'LoadFrom'。 B型起源于   'ClassLibrary1,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'   在位置'C:\ Users \ Nikola \ Documents \ Visual'的上下文'Default'中   工作室   2010 \项目\ ConsoleApplication12 \ ConsoleApplication12 \ BIN \调试\ ClassLibrary1.dll”。

那么,如何解决呢?

您只需使用Assembly.Load("ClassLibrary1")加载程序集即可。这将确保您在单个上下文中工作,并且您的原始代码将起作用。

查看this blogpost,其中包含您遇到的完全相同的问题。阅读有关load contexts的内容可能会有所帮助。

答案 1 :(得分:-2)

var attribs = (MyAttribute1)type.GetCustomAttributes(typeof(MyAttribute1), false)[someIndex];