2012-05-15 58 views
3

我目前在nHibernate上切齒,並有一個關於動態訪問我的持久對象中的屬性的問題。在NHibernate中動態引用屬性?

我在Domain以下類:

public class Locations { 
    public virtual string CountryCode; 
    public virtual string CountryName; 
} 

現在,假設我有一個位置參考對象,有什麼辦法讓我做這樣的事情?

Locations myCountry = new LocationsRepository().GetByCountryCode("US"); 
myCountry.Set("CountryName", "U.S.A."); 

,而不必做:

myCountry.CountryName = "U.S.A." 

沒有反映?

回答

1

我討厭在StackOverflow上回答自己的問題,並且我很感謝大家的迴應,但他們都沒有爲我做過。經過一番研究,我發現NHibernate的最新版本提供dynamic models

雖然方便,但他們的實驗性使我有點在生產中使用它們,所以我做了一些更多的研究。我發現SE自己的Marc Gravell繼承了他的HyperDescriptor庫,名爲Fastmember。它利用DLR提供的速度增益,並將其與簡單的反射語法一起使用。我在我的基本實體類中實現了FastMember訪問,並將其作爲簡單的GetValue和SetValue方法,並且在業務中。

+0

+1如果您使用Fastmember顯示代碼,您可能會獲得更多投票。圖書館還很新。它可能有助於說明爲什麼你的答案實際上是最好的答案,並給人們一個嘗試Fastmember的理由。 – jsmith

0

沒有反映,這可能是一個想法:

public class Locations 
{ 
    private Dictionary<string, object> _values; 
    public Locations() 
    { 
    _values = new Dictionary<string, object>(); 
    } 
    public void Set(string propertyName, object value) 
    { 
    if(!_values.ContainsKey(propertyName)) 
     _values.Add(propertyName, value); 
    else 
     _values[propertyName] = value; 
    } 
    public object Get(string propertyName) 
    { 
    return _values.ContainsKey(propertyName) ? _values[propertyName] : null; 
    } 

    public string CountryCode 
    { 
    get{ return Get("CountryCode"); } 
    set{ Set("CountryCode", value); } 
    } 
} 

這樣,您能夠在不受反射來訪問屬性,並使用一個單一的方法來改變它們。我沒有測試過這個代碼,但我希望這是你的意思,「沒有直接訪問財產。」

1

如果您避免反射的目標是提高性能,那麼一個簡單的解決方案是硬編碼,像這樣所有屬性的功能:

public class Locations { 
    public virtual string CountryCode; 
    public virtual string CountryName; 

    public void Set(string propertyName, string value) { 
     if (propertyName == "CountryCode") this.CountryCode = value; 
     else if (propertyName == "CountryName") this.CountryName = value; 
     else throw new ArgumentException("Unrecognized property '" + propertyName + "'"); 
    } 
} 

你可以很容易地通過使用T4 templates使這種方法成立以編程方式爲所有的域類生成Set方法。實際上,我們在自己的代碼庫中執行類似的事情,使用T4模板生成適配器和序列化程序,以避免在運行時反映代價,同時在編譯時獲得用於代碼生成的反射靈活性。

1

我知道你說的「無反射」,但反思不是一件壞事(當然不是夠慢的人做出來的人),所以它的價值的反射解決方案的提及在這裏:

using System.Reflection; 

typeof(Locations).GetProperty("CountryName").SetValue(myCountry, "U.S.A.", null); 

poof,完成。

1

您正在尋找一些行爲類似於具有屬性的普通對象,並且像字典一樣。如果你使用.NET4,你可以看看ExpandoObject