NHibernate mapping with no empty constructor and no setters

R. *_*des 3 mapping nhibernate orm nhibernate-mapping

I'm testing how difficult it is to use NHibernate with a domain that is completely unaware of it and isn't bent to accodomate any limitations.

On many examples I found on the web the domain being mapped is yet another example of an anemic domain, where objects don't go far from being simple data holders. Sure, this makes the mapping simple and all and it might appeal to data-centric persons/situations, but I don't like hearing the voices in my head that say "C has structs too, you know?", "Classes are not just fancy namespaces, you know?", or "Why don't you use CREATE TABLE instead?".

但回到NHibernate.NHibernate强迫我使属性虚拟,以便能够代理它们进行延迟加载.这是我不介意的事情,因为我可能也需要它们作为一些AOP的虚拟东西.我不满意的限制是需要一个空的构造函数以及对setter/properties的需求.我希望我的实体在有效状态下创建,大多数时候这意味着没有空构造函数.出于通常的原因,我也不想为集合属性公开setter.哦,以及不应该直接更改的属性的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

大多数属性都没有setter,并且看不到空构造函数.集合不是直接插入,而是通过专门的方法.我可以利用NHibernate的可扩展性来映射这个吗?或者我想再次敲击螺丝钉?或两者?

Jag*_*uar 8

那么你可以在属性/集合上放置私有/内部/受保护的setter,而nhibernate将正确加载它们(第4.1.1节)

构造函数必须在那里,但你没有义务将其作为公共构造者(第4.1.2章)

最新的http://sourceforge.net/projects/nhibernate/files/NHibernate/2.1.2GA/NHibernate-2.1.2.GA-reference.zip/download