Я проверяю, насколько сложно использовать NHibernate с доменом, который совершенно не знает об этом и не склонен учитывать любые ограничения.
Во многих примерах, которые я обнаружил в Интернете, сопоставляемый домен является еще одним примером анемичного домена, где объекты не уходят далеко от простых носителей данных. Конечно, это делает сопоставление простым и всем, и это может обратиться к лицам / ситуациям, ориентированным на данные, но мне не нравится слышать голоса в моей голове, которые говорят: «С тоже имеет структуру, понимаете?», «Классы не являются вы знаете, просто причудливые пространства имен? »или« Почему бы вместо этого не использовать CREATE TABLE? ».
Но вернемся к NHibernate. NHibernate заставляет меня сделать свойства виртуальными, чтобы иметь возможность прокси их для ленивой загрузки. Это то, что я не возражаю, так как они могут понадобиться как виртуальные для некоторых AOP.
Ограничения, которые меня не устраивают, - это необходимость в пустом конструкторе и необходимость в установщиках / свойствах. Я хочу, чтобы мои сущности были созданы в допустимом состоянии, и в большинстве случаев это означает, что нет пустого конструктора.
Я также не хочу выставлять сеттеры для свойств коллекции по обычным причинам. Да, и сеттеры для атрибутов, которые не должны изменяться напрямую.
Рассмотрим этот упрощенный и надуманный агрегат в доменной модели где-то:
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, чтобы отобразить это? Или я снова пытаюсь вбить винт? Или оба?