2012-05-15 35 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