DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)
前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调
领域逻辑与仓储持久化。
首先大家需要明确的是,产品上下文的领域逻辑是系统的核心,它不应该依赖仓储,而仓储应该要依赖领域层,这样仓储才可以把领域逻辑执行完后,才可能将
领域对象持久化到数据库中,这一点与传统的架构有本质的区别。
一般我们会在解决方案中建立一个项目,这个项目就是包含了所有聚合的仓储实现,具体不同上下文的仓储实现,可以在这个项目下建立不同的文件夹。
1.产品上下文仓储实现:
public class ProductEFCoreRepository : IProductRepository
{
private readonly DbContext context;
public ProductEFCoreRepository(DbContext context)
{
this.context = context;
}
public void CreateProduct<T>(T productspu) where T:class,IAggregationRoot
{
var productdbcontext = this.context as ProductEFCoreContext;
var productspunew = productspu as ProductSPU;
try
{
productdbcontext.ProductSPU.Add(productspunew);
}
catch(Exception error)
{
throw error;
}
} }
上面的代码有几个要注意的方面:
a.首先会从产品的仓储接口做继承,通过EF Core的机制,实现了仓储接口的CreateProduct方法。
b.使用了产品上下文的EF Core数据访问上下文ProductEFCoreContext完成了Productspu的数据库预添加。
c.上一个说法中,可能大家有两个疑惑,一是为什么不使用productdbcontext标记ProductSPU为Added状态,而是使用.Add方法,二是为什么只是完成了添加状态,
而不再后续调用Commit或SaveChange方法真正持久化到数据库中?首先,因为未来持久化要将这个聚合中的ProductSPU聚合根与ProductSKU实体作为一个整体持久化到数据库中,
而Added状态只能将当前聚合根作为添加状态,而不能同时将引用的ProductSKU对象作为添加状态,所以不能使用Added状态而使用.Add方法;其次仓储实现聚合提交时,只进行数
据库预添,是因为协调领域逻辑与仓储的应用服务层用例可能涉及到多个聚合,所以可能要同时调用多个领域对象的业务逻辑,多个仓储,完成后,将多
聚合作为一个整体事务做提交,所以真正的提交应该放到应用服务层更合适,而不是仓储层。
2.产品上架应用服务层实现:
应用服务层实际就是完成用例,通过应用服务层调用领域逻辑,然后通过应用服务层调用仓储,最后应用服务层做真正的提交,这样就把职责分的非常清楚,也在领域逻辑不依赖
仓储的前提下,完成了整个用例和持久化。
a.首先我们在产品上下文的应用服务层项目中,建立需要添加的产品SPU与对应产品SKU的DTO对象
public class AddProductSPUDTO
{
public string SPUName { get; set; }
public string SPUDesc { get; set; }
public List<string> SKUSpecs { get; set; }
public List<string> SKUUnits { get; set; }
public List<decimal> SKUDealerPrices { get; set; }
public List<byte[]> SKUImages { get; set; }
public List<decimal> SKUPvs { get; set; }
}
b.建立一个上架产品的用例服务,协调领域逻辑与仓储完成用例
public class AddProductSPUUseCase:BaseAppSrv
{
private readonly IRepository irepositorycontext;
private readonly IProductRepository iproductrepository;
public AddProductSPUUseCase(IRepository irepositorycontext,IProductRepository iproductrepository)
{
this.irepositorycontext = irepositorycontext;
this.iproductrepository = iproductrepository;
} public ResultEntity<bool> AddProduct(AddProductSPUDTO addproductspudto)
{
var productspuid = Guid.NewGuid();
var productskus = new List<ProductSKU>();
for(int i = ; i < addproductspudto.SKUSpecs.Count; i++)
{
var productsku = new ProductSKU().CreateProductSKU(addproductspudto.SPUName,
productspuid, addproductspudto.SKUImages[i], addproductspudto.SKUDealerPrices[i],
addproductspudto.SKUPvs[i], addproductspudto.SKUUnits[i], addproductspudto.SKUSpecs[i]);
productskus.Add(productsku);
}
var productspu = new ProductSPU().CreateProductSPU(productspuid, addproductspudto.SPUName,
addproductspudto.SPUDesc, productskus);
try
{
using (irepositorycontext)
{
iproductrepository.CreateProduct(productspu);
irepositorycontext.Commit();
}
return GetResultEntity(true);
}
catch(Exception error)
{
throw error;
}
}
}
BaseAppSrv是你要定义的一个类,它的GetResultEntity方法功能是完成用例后后,返回接口层的数据格式,这个数据格式会进一步通过接口层返回给前端,返回
的数据格式就是ResultEntity<T>,这两个部分大家可以自己去实现,也可以参考我的微信公众号中的课程。
QQ讨论群:309287205
DDD实战进阶视频请关注微信公众号:
DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)的更多相关文章
- DDD实战进阶第一波(十二):开发一般业务的大健康行业直销系统(订单上下文POCO模型)
在本系列前面的文章中,我们主要讨论了产品上下文与经销商上下文相关的实现,大家对DDD的方法与架构已经有了初步的了解. 但是在这两个界限上下文中,业务逻辑很简单,也没有用到更多的值对象的内容.从这篇文章 ...
- DDD实战进阶第一波(十四):开发一般业务的大健康行业直销系统(订单上下文应用服务用例与接口)
上一篇文章我们主要讲了订单上下文的领域逻辑,在领域逻辑中完成了订单项的计算逻辑.订单的计算逻辑以及如何生成相应的实体code,这篇文章我们通过 在应用服务中实现一个下单的用例,来将这些领域逻辑以及仓储 ...
- DDD实战进阶第一波(十三):开发一般业务的大健康行业直销系统(订单上下文领域逻辑)
前一篇文章主要讲了订单上下文的POCO模型,其中订单与订单项中有大量的值对象.这篇文章主要讲讲这些值对象以及订单项.订单相关的领域逻辑. 1.ProductSKUs值对象领域逻辑:ProductSKU ...
- DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述)
本系列文章 DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述) DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一) 近年来,关于如何开发基于 ...
- DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一)
要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍 ...
- DDD实战进阶第一波(八):开发一般业务的大健康行业直销系统(业务逻辑条件判断最佳实践)
这篇文章其实是大健康行业直销系统的番外篇,主要给大家讲讲如何在领域逻辑中,有效的处理业务逻辑条件判断的最佳实践问题. 大家都知道,聚合根.实体和值对象这些领域对象都自身处理自己的业务逻辑.在业务处理过 ...
- DDD实战进阶第一波(三):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架二)
了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的架构,只有了解了经典DDD的架构,你才能 ...
- DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)
从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...
- DDD实战进阶第一波(十五):开发一般业务的大健康行业直销系统(总结篇)
前面我们花了14篇的文章来给大家介绍经典DDD的概念.架构和实践.这篇文章我们来做一个完整的总结,另外生成一个Api接口文档. 一.DDD解决传统的开发的几大问题: 没有描述需求的设计模型:而是直接通 ...
随机推荐
- 光环国际联合阿里云推出“AI智客计划”
2018阿里巴巴云栖大会深圳峰会3月28日.29日在大中华喜来登酒店举行,阿里云全面展示智能城市.智能汽车.智能生活.智能制造等产业创新. 3月28日下午,以"深化产教融合,科技赋能育人才& ...
- spring MVC 原理及源码解析
首先要知道springmvc的核心控制器dispatcherServlet(继承自httpServlet) 一般httpServlet的请求过程: 1.初始化(创建servlet实例时)时会执行ser ...
- Win调整和小技巧
推荐win下一些个人爱用的工具软件(以及使用心得)和一些系统调整方法,让win下不尽人意的设置发生小小变化,让整天摸着电脑的ITer们的生活更有乐趣. 本人酷爱收集一些好用的软件,若各位也对某个或某些 ...
- linux dd使用记录
dd if=/dev/sda of=/dev/sdb bs=10M Linux下显示dd命令的进度: dd if=/dev/zero of=/tmp/zero.img bs=10M count=100 ...
- Java字符串的split(String str)方法空串的问题
String strs[] = "SS1BB2CC3".split("\\D+"); public static String Test(){ Date d = ...
- verilog学习笔记(1)_两个小module
第一个小module-ex_module module ex_module( input wire sclk,//声明模块的时候input变量一定是wire变量 input wire rst_n,// ...
- Hibernate之HQL
SQL语句的DML操作不外乎:增,删,改,查 增加 : save(),persist() 删除 : delete() 改动 : update() 查询 : get() ,load() 其 ...
- SDOI2017 相关分析
把两个式子拆开 Σ(xi-px)(yi-py) =Σ xiyi + py * Σ xi - px * Σ yi + Σ 1* px * py Σ (xi-px)² = Σ xi² + px * Σ ...
- 老板怎么办,我们网站遭到DDoS攻击又挂了?
相信现在正在阅读此文的你,一定听说过发生在上个月的史上最大的DDoS攻击. 美国东部时间2月28日,GitHub在一瞬间遭到高达1.35Tbps的带宽攻击.这次DDoS攻击几乎可以堪称是互联网有史以来 ...
- Python之旅.第二章数据类型 3.19/3.20/3.21/3.22/3.23
一.数字类型 1.int类型: 基本使用: 用途:用于年龄,手机号,身份证号: 定义: age=18: 常用操作+内置方法: 正常的运算赋值: 进制转换: print(bin(3)); 把十进制3转换 ...