我测试了使用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