上一篇文章我们主要讲了订单上下文的领域逻辑,在领域逻辑中完成了订单项的计算逻辑、订单的计算逻辑以及如何生成相应的实体code,这篇文章我们通过

在应用服务中实现一个下单的用例,来将这些领域逻辑以及仓储整合起来,完成一个下单的用例。

先看下单用例主体的代码:

 public class CreateOrderUseCase:BaseAppSrv
{
private readonly IOrderRepository iorderrepository;
private readonly IDealerRepository idealerrepository;
private readonly IRepository[] irepositories; public CreateOrderUseCase(IOrderRepository iorderrepository,IDealerRepository idealerrepository,
params IRepository[] irepositories)
{
this.iorderrepository = iorderrepository;
this.idealerrepository = idealerrepository;
this.irepositories = irepositories;
}
public ResultEntity<bool> CreateOrder(OrderDTO orderdto)
{
var orderid = Guid.NewGuid();
Orders order = new Orders();
var productskus = new List<ProductSKU>();
for(int i = 0; i < orderdto.ProductSPUNames.Count; i++)
{
var productsku = new ProductSKU();
productsku.ProductSPUName = orderdto.ProductSPUNames[i];
productsku.DealerPrice = orderdto.ProductDealerPrices[i];
productsku.PV = orderdto.ProductPVS[i];
productsku.Id = orderdto.ProductSKUIds[i];
productsku.Spec = orderdto.ProductSepcs[i];
productskus.Add(productsku);
}
var contact = new Contact();
contact.ContactName = orderdto.ContactName;
contact.ContactTel = orderdto.ContactTel;
contact.Province = orderdto.Privence;
contact.City = orderdto.City;
contact.Zero = orderdto.Zero;
contact.Street = orderdto.Street; var orders = order.CreateOrders(orderid, orderdto.DealerId, productskus, orderdto.Counts,
contact); try
{
//using (var tansaction = new TransactionScope())
//{
using (irepositories[1])
{
idealerrepository.SubParentEleMoney(orderdto.DealerId, order.OrderTotalPrice.TotalPrice);
idealerrepository.AddDealerPV(orderdto.DealerId, order.OrderTotalPV.TotalPV);
irepositories[1].Commit(); } using (irepositories[0])
{
iorderrepository.CreateOrder(orders);
irepositories[0].Commit();
}
return GetResultEntity(true);
//tansaction.Complete();
//}
}
catch(EleMoneyNotEnoughException error)
{
throw error;
}
catch(Exception error)
{
throw error;
} }
}

IOrderRepository仓储接口主要完成订单的预持久化工作,我们来看下它的实现:

public class OrderEFCoreRepository : IOrderRepository
{
private readonly DbContext context; public OrderEFCoreRepository(DbContext context)
{
this.context = context;
}
public void CreateOrder<T>(T order) where T:class,IAggregationRoot
{
var ordercontext = this.context as OrderEFCoreContext;
var ordernew = order as Orders;
try
{
ordercontext.Order.Add(ordernew);
}
catch(Exception error)
{
throw error;
}
}
}

IDealerRepository仓储接口主要用来下单完成后,扣减对应经销商的电子币与累加PV,相关方法实现代码如下:

public void SubParentEleMoney(Guid parentdealerid, decimal subelemoney)
{
var dealercontext = this.context as DealerEFCoreContext;
var parentdealer = dealercontext.Dealer.Single(p => p.Id == parentdealerid);
parentdealer.TotalEleMoney = parentdealer.TotalEleMoney - subelemoney;
if (parentdealer.TotalEleMoney < 0)
{
throw new EleMoneyNotEnoughException("电子币不够进行此操作!");
}
try
{
dealercontext.Entry(parentdealer).State = EntityState.Modified;
}
catch(Exception error)
{
throw error;
}
} public void AddDealerPV(Guid dealerid, decimal orderpv)
{
var dealercontext = this.context as DealerEFCoreContext;
var dealer = dealercontext.Dealer.Single(p => p.Id == dealerid);
dealer.TotalPV = dealer.TotalPV +orderpv;
try
{
dealercontext.Entry(dealer).State = EntityState.Modified;
}
catch (Exception error)
{
throw error;
}
}

IRepository[]用于订单与经销商两个的数据访问仓储,完成真正的持久化,在第一部分主体代码中注释掉的using (var tansaction = new TransactionScope())与

tansaction.Complete();是因为在.net core 2.0版本中,不支持多个数据访问上下文的事务,在.net core 2.1版本中可以使用,这样就完成了订单数据与经销商

数据的事务一致性。

最后我们通过webapi完成对应用服务的调用,实现代码如下。

[HttpPost]
[Route("CreateOrder")]
public ResultEntity<bool> CreateOrder([FromBody] OrderDTO orderdto)
{
var result = new ResultEntity<bool>();
var ordercontext = new OrderEFCoreContext();
var dealercontext = new DealerEFCoreContext();
var irepository = new EFCoreRepository(ordercontext);
var irepository1 = new EFCoreRepository(dealercontext);
var iorderrepository = new OrderEFCoreRepository(ordercontext);
var idealerrepository = new DealerEFCoreRepository(dealercontext);
var createorderusecase = new CreateOrderUseCase(iorderrepository, idealerrepository,
irepository, irepository1);
try
{
result = createorderusecase.CreateOrder(orderdto);
result.Count = 1;
result.IsSuccess = true;
result.Msg = "下单成功!";
}
catch (EleMoneyNotEnoughException error)
{
result.ErrorCode = 300;
result.Msg = error.Message;
}
catch (Exception error)
{
result.ErrorCode = 200;
result.Msg = error.Message;
}
return result;
}

因为这里只是做演示,具体接口与实现没有通过依赖注入框架注入,这部分内容可以自己去实现。

QQ讨论群:309287205

DDD实战进阶视频请关注微信公众号:

DDD实战进阶第一波(十四):开发一般业务的大健康行业直销系统(订单上下文应用服务用例与接口)的更多相关文章

  1. DDD实战进阶第一波(十):开发一般业务的大健康行业直销系统(实现经销商登录仓储与逻辑)

    上一篇文章主要讲了经销商注册的仓储和领域逻辑的实现,我们先把应用服务协调完成经销商注册这部分暂停一下,后面文章统一讲. 这篇文章主要讲讲经销商登录的仓储和相关逻辑的实现. 在现代应用程序前后端分离的实 ...

  2. DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述)

    本系列文章 DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述) DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一) 近年来,关于如何开发基于 ...

  3. DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一)

    要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍 ...

  4. DDD实战进阶第一波(八):开发一般业务的大健康行业直销系统(业务逻辑条件判断最佳实践)

    这篇文章其实是大健康行业直销系统的番外篇,主要给大家讲讲如何在领域逻辑中,有效的处理业务逻辑条件判断的最佳实践问题. 大家都知道,聚合根.实体和值对象这些领域对象都自身处理自己的业务逻辑.在业务处理过 ...

  5. DDD实战进阶第一波(三):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架二)

    了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的架构,只有了解了经典DDD的架构,你才能 ...

  6. DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)

    从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...

  7. DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)

    前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调 领域逻辑与仓储持久化. 首先大家需要明确的是,产品上下文 ...

  8. DDD实战进阶第一波(九):开发一般业务的大健康行业直销系统(实现经销商上下文仓储与领域逻辑)

    上篇文章主要讲述了经销商上下文的需求与POCO对象,这篇文章主要讲述该界限上下文的仓储与领域逻辑的实现. 关于界限上下文与EF Core数据访问上下文参考产品上下文相应的实现,这里不再累述. 因为在经 ...

  9. DDD实战进阶第一波(十一):开发一般业务的大健康行业直销系统(实现经销商代注册用例与登录令牌分发)

    前两篇文章主要实现了经销商代注册的仓储与领域逻辑.经销商登录的仓储与相关逻辑,这篇文章主要讲述经销商代注册的用例与经销商登录的查询功能. 一.经销商代注册用例 在经销商代注册用例中,我们需要传递经销商 ...

  10. DDD实战进阶第一波(十三):开发一般业务的大健康行业直销系统(订单上下文领域逻辑)

    前一篇文章主要讲了订单上下文的POCO模型,其中订单与订单项中有大量的值对象.这篇文章主要讲讲这些值对象以及订单项.订单相关的领域逻辑. 1.ProductSKUs值对象领域逻辑:ProductSKU ...

随机推荐

  1. ssh 免密登录阿里云主机

    在网上找了好几篇教程,都不好使. 终于在这篇找到了答案 解决方案: 在 sshd_config 里面将这一项: AuthorizedKeysFile .ssh/authorized_keys 被我修改 ...

  2. 20155312 张竞予 Exp7 网络欺诈防范

    Exp7 网络欺诈防范 目录 基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击 (2)在日常生活工作中如何防范以上两攻击方法 实验总结与体会 实践过程记录 (1)简单应用SET工具建 ...

  3. random模块,生成随机数

    1.random.choice(sep) 从一个序列中随机选取一个元素返回 >>> list1=["a",1,2,3,"b"] >> ...

  4. 关于下载calipso数据集以及用python将其读到记事本小结

    今天终于把老板交代的事情忙完了,对于我这位计算机语言的小白来说,其中的艰辛不用说,一把辛酸泪啊!在有计算机语言经验的老手而言,我这些问题似乎也不能算是问题,但我却卡了很久,对此,想把自己所遇到的困难和 ...

  5. 2019.03.28 bzoj3597: [Scoi2014]方伯伯运椰子(01分数规划)

    传送门 题意咕咕咕有点麻烦不想写 思路: 考虑加了多少一定要压缩多少,这样可以改造边. 于是可以通过分数规划+spfaspfaspfa解决. 代码: #include<bits/stdc++.h ...

  6. Elasticsearch System Call Filters Failed to Install

    Elasticsearch starts to run, error occurs: : system call filters failed to install; check the logs a ...

  7. How to setup Visual Studio without pain

    Visual Studio (VS) can be very hard to install. If you are lucky, one whole day may be enough to ins ...

  8. some knowledge of the IT world

    IT世界一切皆是可信息化(数据的转换)即信息记录一切,对信息的控制{存储,运算,传输{信息的位置转移},转换}就是对一切的控制{硬件(实质维)以信息的控制{软件形式(存在维)}进行操作} 信息本身的实 ...

  9. sqlserver 多行转一行

    sql 例子: SELECT STUFF((SELECT ',' + CONVERT(VARCHAR, b.SCsinfoSourceId) FROM PZDataCsinfo b WHERE b.D ...

  10. Hibernate知识总结(一)

    一.ORM ORM的全称是Object/Relation Mapping,即对象/关系映射,可以将其理解成一种规范,它概述了这类框架的基本特征:完成面向对象的编程语言到关系数据库的映射.可以把ORM看 ...