我測試了使用NHibernate與一個完全不知道它的域並且不想屈服於任何限制的困難。NHibernate映射,沒有空的構造函數和沒有setter
在網上發現的很多例子中,被映射的域是貧血域的另一個例子,對象離簡單的數據持有者並不遙遠。當然,這使得映射變得簡單和全面,它可能會吸引以數據爲中心的人/情境,但我不喜歡聽到我腦海中的聲音說「C也有結構,你知道嗎?」,「類不是隻是很花哨的命名空間,你知道嗎?「,或者」你爲什麼不用CREATE TABLE?「。
但是回到NHibernate。 NHibernate迫使我使虛擬屬性能夠代理它們進行延遲加載。這是我不介意的,因爲我也可能需要它們作爲虛擬的AOP。 我不滿意的侷限性是需要一個空的構造函數以及對setter /屬性的需要。我希望我的實體能夠在有效狀態下創建,並且大部分時間表示沒有空的構造函數。 我也不想公開收集屬性的setters,通常的原因。噢,以及那些不應該直接改變的屬性的setter。
考慮這個簡化和做作聚集在一個域模型的地方:
public class ShoppingCartItem
{
private readonly Product product;
public ShoppingCartItem(Product product, int quantity)
{
if(quantity <= 0)
throw new ArgumentOutOfRangeException("quantity");
this.product = product;
this.quantity = quantity;
}
public virtual Product Product
{
get { return product; }
}
private int quantity;
public virtual int Quantity
{
get { return quantity; }
set
{
if(value <= 0)
throw new ArgumentOutOfRangeException("value");
quantity = value;
}
public virtual Money TotalPrice
{
get { return product.Price * quantity; }
}
}
public class ShoppingCart : Entity
{
private readonly IDictionary<Product, ShoppingCartItem> items =
new Dictionary<Product, ShoppingCartItem>();
private readonly ISet<DiscountCoupon> discountCoupons =
new HashSet<DiscountCoupon>();
public virtual IEnumerable<ShoppingCartItem> Items
{
get { return items.Values; }
}
public virtual IEnumerable<DiscountCoupon> DiscountCoupons
{
get { return discountCoupons; }
}
public virtual void AddProduct(Product product)
{
ShoppingCartItem item;
if(items.TryGetValue(product, out item))
item.Quantity++;
else
items.Add(product, new ShoppingCartItem(product, 1));
}
public virtual void RemoveProduct(Product product)
{
ShoppingCartItem item;
if(!items.TryGetValue(product, out item))
throw new ArgumentException("product");
if(item.Quantity == 1)
items.Remove(product);
else
item.Quantity--;
}
public virtual int AddDiscountCoupon(DiscountCoupon coupon)
{
discountCoupons.Add(coupon);
}
public virtual int RemoveDiscountCoupon(DiscountCoupon coupon)
{
discountCoupons.Remove(coupon);
}
public virtual Money CalculatePrice()
{
// Missing complex discount logic
return items.Values.Sum(item => item.TotalPrice);
}
}
大多數屬性都沒有二傳手,有沒有空的構造函數在望。集合不直接干涉,而是通過專門的方法。我可以使用NHibernate的可擴展性來映射這個嗎?或者我想再次敲一顆螺絲?或兩者?
事實上,訪問策略並不總是需要明確定義的 – Jaguar 2010-06-08 16:14:35
這是不完全正確的。構造函數應該受到保護。從異常:「NHibernate.InvalidProxyTypeException:下列類型不能用作代理: ClassA:類型應該有一個可見(公共或受保護的)無參數構造函數」。文檔(4.1.2)說:「類必須有一個默認的構造函數(可能是非公有的)」 – esegura 2010-12-21 16:02:49