在我的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 调用获取任何属性。我究竟做错了什么?请帮忙。感谢
答案 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];