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

领域逻辑与仓储持久化。

首先大家需要明确的是,产品上下文的领域逻辑是系统的核心,它不应该依赖仓储,而仓储应该要依赖领域层,这样仓储才可以把领域逻辑执行完后,才可能将

领域对象持久化到数据库中,这一点与传统的架构有本质的区别。

一般我们会在解决方案中建立一个项目,这个项目就是包含了所有聚合的仓储实现,具体不同上下文的仓储实现,可以在这个项目下建立不同的文件夹。

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实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)的更多相关文章

  1. DDD实战进阶第一波(十二):开发一般业务的大健康行业直销系统(订单上下文POCO模型)

    在本系列前面的文章中,我们主要讨论了产品上下文与经销商上下文相关的实现,大家对DDD的方法与架构已经有了初步的了解. 但是在这两个界限上下文中,业务逻辑很简单,也没有用到更多的值对象的内容.从这篇文章 ...

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

    上一篇文章我们主要讲了订单上下文的领域逻辑,在领域逻辑中完成了订单项的计算逻辑.订单的计算逻辑以及如何生成相应的实体code,这篇文章我们通过 在应用服务中实现一个下单的用例,来将这些领域逻辑以及仓储 ...

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

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

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

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

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

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

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

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

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

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

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

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

  9. DDD实战进阶第一波(十五):开发一般业务的大健康行业直销系统(总结篇)

    前面我们花了14篇的文章来给大家介绍经典DDD的概念.架构和实践.这篇文章我们来做一个完整的总结,另外生成一个Api接口文档. 一.DDD解决传统的开发的几大问题: 没有描述需求的设计模型:而是直接通 ...

随机推荐

  1. 解决NSURLConnection finished with error - code -1100错误

    更新到xcode9以后,拖进工程中一个html文件,webview加载这个文件,xcode一直抛出 NSURLConnection finished with error - code -1100异常 ...

  2. Elasticsearch安装详解

    本文只介绍在windows上的安装和配置,其他安装和配置请参见官方文档 ES在windows上安装需下载zip安装包,解压后bin目录下有个 elasticsearch-service.bat 文件. ...

  3. Java并发编程实战(chapter_2)(对象发布、不变性、设计线程安全类)

    一.发布与溢出 "发布(Publish)"一个对象的意思是指,使对象能够在当前作用于之外的代码中使用.这个"之外",尤为关键,各种出问题的地方,都是因为这个&q ...

  4. 第七周PTA作业

    第一题: #include<stdio.h> int main() { ; ; ){ sum=sum+i; i++; } printf("sum = %d\n",sum ...

  5. C语言第一次博客作业 陈张鑫

    一,PTA实验作业 题目1.温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验代 ...

  6. 每日冲刺报告--Day2

    敏捷冲刺每日报告--Day2 情况简介 今天我们三个人在一起开了会,分析了我们面临的情况以及下一阶段的计划.一个重大的改进是,我们准备把之前用txt文件格式存储订阅列表改成了文件json格式. 任务进 ...

  7. 十款不容错过的Swift iOS开源项目及介绍

    1.十款不容错过的Swift iOS开源项目. http://www.csdn.net/article/2014-10-16/2822083-swift-ios-open-source-project ...

  8. 服务器磁盘阵列数据恢复,raid5两块硬盘掉线数据恢复方法

    [用户单位信息] 农业科学研究院某研究所 [磁盘阵列故障发生过程描述]客户的DELL MD1000服务器内置15块1TB硬盘搭建为RAID5磁盘阵列阵列,服务器在正常工作中有一块硬盘离线,管理员对磁盘 ...

  9. js 中bind

    function fn(a){ this.innerHTML = a; console.log(this); } //fn("hello"); span1.onclick =fun ...

  10. Docker学习笔记 - Docker容器内部署redis

    Docker学习笔记(2-4)Docker应用实验-redist server 和client的安装使用 一.获取redis容器(含客户端和服务端) 二.创建服务端容器 1.在终端A中运行redis- ...