2012-07-16 103 views
2

在我MiddleTier項目回來解決方案,我有客戶類,與ATTRIBUTE1無法獲取屬性從GetCustomAttributes

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

我猜測,運行時可能以某種方式考慮爲MiddleTier.dll編譯的「MyAttribute1」類型與在當前域的運行時加載的「MyAttribute1」類型不同。 – 2012-07-16 19:26:02

+0

您可以嘗試調用非類型重載'GetCustomAttributes(false)',然後檢查條目的類型。像'if(attribs.Length> 0){Console.WriteLine(attribs [0] .GetType()== typeof(MyAttribute1)); }' – 2012-07-16 19:27:32

回答

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, 版本= 1.0.0.0,Culture = neutral,PublicKeyToken = null'在上下文 'LoadFrom'位置'C:\ ClassLibrary1.dll'。類型B源自 'C:\ Users \ Nikola \ Documents \ Visual Studio'上下文'Default'中的ClassLibrary1,Version = 1.0.0.0 \ ConsoleApplication12 \ BIN \調試\ ClassLibrary1.dll」。

那麼,如何解決呢?

您只需使用Assembly.Load("ClassLibrary1")即可加載程序集。這將確保您在單個環境中工作,並且您的原始代碼將起作用。

檢查出this blogpost,它對待您遇到的完全相同的問題。閱讀有關load contexts的內容也可能會有所幫助。

+0

謝謝!!!工作完美 – 2012-07-16 20:56:59

+0

我曾經遇到過有人在另一個項目中鏈接了源文件,並且我引用了這兩個程序集(使用相同的源文件),並且在源文件中定義的屬性不起作用。 – Bronek 2015-04-06 19:49:54

-2

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

+0

對,你需要將它作爲你的屬性類型。 – 2012-07-16 18:59:38

+0

實際上,這會返回一個類型的對象數組,因此您需要將其轉換爲'MyAttribute1 []'。 – 2012-07-16 19:21:27

+0

其實,我認爲這不能解決問題。 dotnet-practitioner沒有得到任何結果。如果沒有進行轉換,您仍然會收到長度大於0的非空對象數組。 – 2012-07-16 19:24:53