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

领域逻辑与仓储持久化。

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

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

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

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. 『开源』设置系统 主音量(0~100 静音) VolumeHelper 兼容 Xp Win7 .Net 20 AnyCPU

    背景: 近来的生活一团乱麻,没心态写高大上的代码,于是就着手 写了几个 辅助类. 在整理 InkFx.Utils 时,发现有几个 辅助类 只写了定义,没有实现函数体,于是就 花了1天时间 完善了一下. ...

  2. 2017-2018-1 Java演绎法 第二周 作业

    团队任务:讨论Android上的游戏软件 参考现代软件工程 第一章 [概论]练习与讨论: 软件有很多种,也有各种分类办法,本次团队任务是讨论选取Android上的一个游戏软件,考虑到每位组员接触的游戏 ...

  3. cpp常用函数总结

    //sprintf sprintf(temp_str_result, "%lf", temp_double); result = temp_str_result; (*begin) ...

  4. 【技巧】Java工程中的Debug信息分级输出接口

    也许本文的标题你们没咋看懂.但是,本文将带大家领略输出调试的威力. 灵感来源 说到灵感,其实是源于笔者在修复服务器的ssh故障时的一个发现. 这个学期初,同袍(容我来一波广告产品页面,同袍官网)原服务 ...

  5. 直方图均衡化及matlab实现

    在处理图像时,偶尔会碰到图像的灰度级别集中在某个小范围内的问题,这时候图像很难看清楚.比如下图: 它的灰度级别,我们利用一个直方图可以看出来(横坐标从0到255,表示灰度级别,纵坐标表示每个灰度级别的 ...

  6. nyoj 过河问题

    过河问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的 ...

  7. nyoj 第几是谁

    第几是谁? 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现在有"abcdefghijkl"12个字符,将其按字典序排列,如果给出任意一种排列, ...

  8. Vue 2.0基础语法:系统指令

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. Vue初体验 新建一个空的项目,引入vue.js文件.写如下代码: &l ...

  9. 码农、黑客和2B程序员之间的区别

    码农: 黑客: 2B程序员: 求2的32次方: 码农: System.out.println(Math.pow(2, 32)); 黑客: System.out.println(1L<<32 ...

  10. app测试中遇到问题总结

    工作总结: 1 这两天由于工作,需要进行抓包,使用了Charles,fidder,发现一个坑点: charles没有抓到返回值的时候,默认是不在列表显示请求信息的,能不能设置,我就不知道了,但是可以在 ...