结合领域驱动设计的SOA分布式软件架构,你还在为这些烦恼?( 三 )


namespace Business.IRepository{public interface IOrderRepository{Order GetOrder(int id);IList GetList();IList GetListByPerson(int personID);int AddOrder(Order order);int DeleteOrder(int id);int UpdateOrder(Order order);int AddOrderItem(OrderItem orderItem);int DeleteOrderItem(int id);}public interface IPersonRepository{int AddPerson(Person person);int AttachPerson(Person person);int UpdatePerson(Person person);Person GetPerson(int id);IList GetList();}}namespace Business.Repository{public class OrderRepository:IOrderRepository{//根据ID获取单个Orderpublic Order GetOrder(int id){BusinessContext _context = new BusinessContext();Order order = null;try{using (TransactionScope scope = new TransactionScope()){//由于OrderItem是Order实体中的一个属性 , 必须通过OrderRepository同步获取var list = _context.Order.Include("OrderItem").Where(x => x.ID == id);if (list.Count() > 0)order = list.First();elseorder = new Order();scope.Complete();}}catch (Exception ex){//出错处理 , 并返回一个空对象Business.Common.ExceptionManager.DataException.DealWith(ex);order = new Order();}_context.Dispose();return order;}....................................}public class PersonRepository:IPersonRepository{public int AddPerson(Person person){return LinqHelp.Add(person);}public Person GetPerson(int id){return LinqHelp.Get(id);}..................................}}在更新Order这种复杂的领域模型时 , 如果要分辨单个OrderItem属性是新建值还是更新值 , 然后分别处理 , 那将是比较麻烦的 , 而且OrderItem只是一个值对象 , ID编码等属性对它没有任何实在意义 。 所以在更新List属性时都会先把它全部删除 , 然后重新加载 , 在OrderItem数量不多的时候 , 这是一种十分有效的方法 。
namespace Business.Repository{public class OrderRepository:IOrderRepository{..................................//更新Order , 因为难以别哪些是原有的OrderItem,哪些OrderItem是新插入//使用简单的方法 , 会先把原有的OrderItem的删除 , 再重新插入public int UpdateOrder(Order order){int returnValue = http://kandian.youth.cn/index/-1;BusinessContext _context = new BusinessContext();try{using (TransactionScope scope = new TransactionScope()){var list = _context.Order.Include("OrderItem").Where(x => x.ID == order.ID);if (list.Count() > 0){//更新Order列Order _order = list.First();_order.Count = order.Count;_order.Delivery = order.Delivery;_order.Favorable = order.Favorable;_order.Freightage = order.Freightage;_order.OrderNumber = order.OrderNumber;_order.PersonID = order.PersonID;_order.Price = order.Price;_order.TotalPrice = order.TotalPrice;//删除原有的订单明细项OrderItemif (list.First().OrderItem.Count != 0)foreach (var item in list.First().OrderItem)DeleteOrderItem(item.ID);//加入新的订单明细项OrderItemif (order.OrderItem.Count != 0){foreach (var item in order.OrderItem){var _orderItem = new OrderItem();_orderItem.Count = item.Count;_orderItem.Goods = item.Goods;_orderItem.OrderID = item.OrderID;_orderItem.Price = item.Price;AddOrderItem(_orderItem);}}returnValue = http://kandian.youth.cn/index/_context.SaveChanges();}elsereturnValue = 0;scope.Complete();}}catch (Exception ex){Business.Common.ExceptionManager.DataException.DealWith(ex);returnValue=-1;}_context.Dispose();return returnValue;}//插入OrderItempublic int AddOrderItem(OrderItem orderItem){return LinqHelp.Add(orderItem);}//删除OrderItempublic int DeleteOrderItem(int id){EntityKey key = new EntityKey("BusinessContext.OrderItem", "ID", id);return LinqHelp.Delete(key);}}}五、领域层的服务1. 例子说明
在第二节已基本介绍过服务的作用了 , 领域层服务的作用主要是为了解决业务上的逻辑问题 , 更多的时候 , 服务是一个与业务相关的动作 。 比如在上述例子中:
在Order表里记录的是每次交易的过程 , 每次商品的送货费(Freightage)为10元 , 当商品价格(Price)超过98元可免费送货 , 当用户 Person积分(Point)超过2000分可获7折优惠(Favorable) , 1000~2000分可获8折 , 1000分以下可有9折 , 最后总体价 格为为(TotalPrice) 。
这复杂的业务逻辑 , 完全可以由一个领域服务类AccountManager来完成
namespace Business.Service.DomainService{public class AccountManager{private Person _person;private Order _order;public AccountManager(Person person, Order order){_person = person;_order = order;}///计算总体收费public void Account(){//计算商品数量GoodsCount();//计算商品价格PriceAccount();//计算优惠等级FavorableAccount();double price1 = (_order.Price - _order.Favorable).Value;//计算运费FreightageAccount(price1);//计算总体价费_order.TotalPrice = price1 + _order.Freightage.Value;}//计算商品数量private void GoodsCount(){_order.Count=0;foreach (var OrderItem in _order.OrderItem)_order.Count += OrderItem.Count;}//商品总体价格private void PriceAccount(){_order.Price = 0;foreach (var OrderItem in _order.OrderItem)_order.Price += OrderItem.Price * OrderItem.Count;}//优惠分为三等 , 积分小于1000有9折 , 小于2000分为8折 , 大于2000为7折private void FavorableAccount(){int point = (int)_person.Point.GetInt();if (point