DDD实战4 实现产品仓储】的更多相关文章

a.要实现仓储,首先要定义仓储接口.在领域层定义仓储接口,IProductRepository.cs. public interface IProductRepository { void CreateProduct<T>(T productspu) where T:class,IAggregationRoot; } 产品持久化仓储的实现不应当在领域层实现,因为领域就和仓储实现紧密的绑定在了一起,导致业务和技术没有分离.之所以把接口定义在领域层是因为,领域层对数据的访问只要调用接口就行了. b…
前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调 领域逻辑与仓储持久化. 首先大家需要明确的是,产品上下文的领域逻辑是系统的核心,它不应该依赖仓储,而仓储应该要依赖领域层,这样仓储才可以把领域逻辑执行完后,才可能将 领域对象持久化到数据库中,这一点与传统的架构有本质的区别. 一般我们会在解决方案中建立一个项目,这个项目就是包含了所有聚合的仓储实现,具体不同上下文的仓储实现,可以在这个项目下建立不同的文件…
从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要是产品的名字和相关描述, 产品SKU包括产品SPU的多个规格,每个规格有不同的价格与PV值.从我们对DDD概念的理解,产品SPU与产品SKU属于同一个聚合,产品SPU是聚合根. 产品上下文主要实现产品的上架功能,为了实现上架功能,我们首先要实现产品上下文的领域POCO模型与领域逻辑, 我们将产品的P…
上篇文章主要讲述了经销商上下文的需求与POCO对象,这篇文章主要讲述该界限上下文的仓储与领域逻辑的实现. 关于界限上下文与EF Core数据访问上下文参考产品上下文相应的实现,这里不再累述. 因为在经销商上下文中有两个聚合,一个是经销商聚合,一个是登录聚合,所以我们需要实现两个仓储接口: 1.经销商仓储接口定义: public interface IDealerRepository { void CreateDealer<T>(T dealer) where T : class, IAggre…
上一篇文章主要讲了经销商注册的仓储和领域逻辑的实现,我们先把应用服务协调完成经销商注册这部分暂停一下,后面文章统一讲. 这篇文章主要讲讲经销商登录的仓储和相关逻辑的实现. 在现代应用程序前后端分离的实现中,通常不是将用户登录的信息存储在服务器端Session,因为会存在服务器Session无法传递的情况,也存在WebApi调用时 无法通过Authorize Attribute判断用户是否已经登录并获取用户身份信息的问题.所以现代应用程序都是由服务器后端返回Token给客户端,客户端将Token存…
要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍然是必要的,为了开发一个支持DDD的框架,首先需要理解DDD的基本概念和 核心的组件. 一.什么是领域驱动设计(DDD) 首先要知道DDD是一种开发理念,核心是维护一个反应领域概念的模型(领域模型是软件最核心的部分,反应了软件的业务本质),然后通过大量模式来指导模型设计 与开发. DDD的一般过程是…
前面我们花了14篇的文章来给大家介绍经典DDD的概念.架构和实践.这篇文章我们来做一个完整的总结,另外生成一个Api接口文档. 一.DDD解决传统的开发的几大问题: 没有描述需求的设计模型:而是直接通过数据库表的方式体现,也就是需求与设计是脱节的. 编码的架构也没有与设计和需求对应起来. 业务逻辑与技术混在一起:业务逻辑可能直接调用的数据访问,这样把业务逻辑与数据访问的技术混在一起. 开发没有层次感和节奏感:系统没有一个统一的约束,开发人员没有一个统一的节奏,这主要体现在随意的编码. Bug 定…
了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的架构,只有了解了经典DDD的架构,你才能知道具体在哪层要实现哪些功能,编写哪些代码,具体在开发DDD的轻量级框架与具体模块代码实现时,才能做到有的放矢. 在这里需要说明的是,我们的大健康行业直销系统有一定的业务复杂性,没有高并发.高性能的需求,所以无论是经销商上下文.产品上下文还是订单上下文的具体实现, 我们都将遵循经典DDD架构,而不是…
目录 学好了DDD,你能做什么? 领域驱动设计:微服务设计为什么要选择DDD? 领域.子域.核心域.通用域和支撑域:傻傻分不清? 限界上下文:定义领域边界的利器 实体和值对象:从领域模型的基础单元看系统设计 聚合和聚合根:怎样设计聚合? 领域事件:解耦微服务的关键 DDD分层架构:有效降低层与层之间的依赖 微服务架构模型:几种常见模型的对比和分析 中台:数字转型后到底应该共享什么? DDD.中台和微服务:它们是如何协作的? 学好了DDD,你能做什么? 我认为,要想应用 DDD,首要任务就是要吃透…
前两篇文章主要实现了经销商代注册的仓储与领域逻辑.经销商登录的仓储与相关逻辑,这篇文章主要讲述经销商代注册的用例与经销商登录的查询功能. 一.经销商代注册用例 在经销商代注册用例中,我们需要传递经销商的基本注册信息,这个信息是做成了DTO对象. 1.经销商注册的DTO对象: public class AddDealerDTO { public string Name { get; set; } public string Tel { get; set; } public decimal EleM…
本系列文章 DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述) DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一) 近年来,关于如何开发基于业务的软件系统与产品一直是软件行业的一个重要内容.对于架构师与软件开发人员来说,开发此类系统头痛的问题大概是以下几个方面: 1.如何将需求准确的转为软件的设计? 2.系统的架构与代码如何有效的体现我们的设计? 3.如何将领域逻辑与技术分离? 4.如何能够让团队人员的开发能够专注与业务,而不是技术本身…
上一篇文章我们主要讲了订单上下文的领域逻辑,在领域逻辑中完成了订单项的计算逻辑.订单的计算逻辑以及如何生成相应的实体code,这篇文章我们通过 在应用服务中实现一个下单的用例,来将这些领域逻辑以及仓储整合起来,完成一个下单的用例. 先看下单用例主体的代码: public class CreateOrderUseCase:BaseAppSrv { private readonly IOrderRepository iorderrepository; private readonly IDealer…
前一篇文章主要讲了订单上下文的POCO模型,其中订单与订单项中有大量的值对象.这篇文章主要讲讲这些值对象以及订单项.订单相关的领域逻辑. 1.ProductSKUs值对象领域逻辑:ProductSKUs值对象用于订单项实体中,它的信息应该来源于产品上下文的ProductSKU实体. public partial class ProductSKUs { public ProductSKUs() { } public ProductSKUs CreateProductSKUs(ProductSKU…
在本系列前面的文章中,我们主要讨论了产品上下文与经销商上下文相关的实现,大家对DDD的方法与架构已经有了初步的了解. 但是在这两个界限上下文中,业务逻辑很简单,也没有用到更多的值对象的内容.从这篇文章开始,我们来讲讲订单界限上下文实现的内容, 里面的业务逻辑相对复杂一些,而且有大量值对象的引入来进行逻辑的处理. 订单上下文的需求主要是生成相应的订单项,每个订单项中有相关的订单产品和购买数量并生成订单项总额.订单项总PV,同时订单项总额 和订单项总PV会累加到订单总额和订单总PV中,同时会根据订单…
上一篇文章我们讲了经典DDD架构对比传统三层架构的优势,以及经典DDD架构每一层的职责后,本篇文章将介绍基础结构层中支持DDD的轻量级框架的主要代码. 这里需要说明的是,DDD轻量级框架能够体现DDD的思想即可,没必要做得很重,你也可以根据理解,自己实现支持DDD的框架. 1.实体.聚合根与值对象的顶层体现 实体顶层定义: public interface IEntity { string Code { get; set; } Guid Id { get; set; } } Id是一个未来存储到…
一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都存放在 Volo.Abp.Ddd.Domain 项目当中. 本篇文章将会侧重于理论讲解,但也只是一个抛砖引玉的作用,关于 DDD 相关的知识可以阅读 Eric Evans 所编写的 <领域驱动设计:软件核心复杂性应对之道>. PS: 该书也是目前我正在阅读的 DDD 理论书籍,因为基于 DDD 理…
这篇文章其实是大健康行业直销系统的番外篇,主要给大家讲讲如何在领域逻辑中,有效的处理业务逻辑条件判断的最佳实践问题. 大家都知道,聚合根.实体和值对象这些领域对象都自身处理自己的业务逻辑.在业务处理过程中,通常会有一些条件判断,当满足这些条件时,会进行不同的后续处理.在传统的实现中,可以通过If Else条件语句进行判断,但If Else语句在复杂领域中来检查是否满足一些业务条件存在以下的问题: 1.      无法很好的显示表达业务条件本身. 2.      无法对多个条件在不同需要的地方进行…
微服务到底怎么拆分和设计才算合理,拆多小才叫微服务?有没有好的方法来指导微服务和中台的设计呢? 深入DDD的核心知识体系与设计思想,带你掌握一套完整而系统的基于DDD的微服务拆分与设计方法,助力落地边界清晰.可持续演进的微服务架构. 欧创新,人保高级架构师,专注基于DDD的微服务设计和开发. DDD实战课,前往 找分享 订阅返现. 学后获得:DDD必知必会10大核心概念:掌握事件风暴与领域建模:上手中台业务建模与设计.…
前一篇文章我们介绍了如何将创建产品的领域逻辑与产品的持久化仓储通过上架产品的用例组织起来,完成了一个功能.在实际的项目中,多种前端的形态比如PC Web. 微信小程序.原生APP等要调用后端的功能,通常要将后端的功能包装成RESTFUL风格,这样前端就可以使用Http Get或Post方式调用后端的功能,所以这篇文章我们先来完成后端 的Asp.net Core WebApi,通过WebApi将上架产品的功能暴露出去. 实现上下产品接口: [Produces("application/json&q…
通过服务来协调领域对象,来添加产品用例. 1.要实现产品上下文的服务,首先新建一个项目,在Product解决方案文件夹下面新建一个项目,项目的名称为:Product.AppSrv. 2.这个项目首先引用Product.Domain项目,因为它操作领域对象,所以还要引用DDD.Repositories(为什么不取名Product.Repository呢,因为这个项目的初衷是放置所有的仓储实现,我们之前在里面定义了ProductRepositories文件夹). 因为它还要用到Util项目里面的东西…
目录 DDD实战与进阶 - 值对象 概述 何为值对象 怎么运用值对象 来看一个例子 值对象的持久化 总结 DDD实战与进阶 - 值对象 概述 作为领域驱动设计战术模式中最为核心的一个部分-值对象.一直是被大多数愿意尝试或者正在使用DDD的开发者提及最多的概念之一.但是在学习过程中,大家会因为受到传统开发模式的影响,往往很难去运用值对象这一概念,以及在对值对象进行持久化时感到非常的迷惑.本篇文章会从值对象的概念出发,解释什么是值对象以及怎么运用值对象,并且给出相应的代码片段(本教程的代码片段都使用…
目录 DDD实践:如何用DDD重构中台业务模型? 领域建模:如何用事件风暴构建领域模型? 代码模型(上):如何使用DDD设计微服务代码模型? 代码模型(下):如何保证领域模型与代码模型的一致性? 边界:微服务的各种边界在架构演进中的作用? 视图:如何实现服务和数据在微服务各层的协作? 从后端到前端:微服务后,前端如何设计? 知识点串讲:基于DDD的微服务设计实例 基于DDD的微服务设计实例代码详解 总结(一):微服务设计和拆分要坚持哪些原则? 总结(二):分布式架构关键设计10问 DDD实践:如…
这里的值对象如下风格: namespace Order.Domain.PocoModels { //订单地址 //虽然是值对象 但是不继承ValueObject //因为继承ValueObject会有Id属性 我们不为它创建独立建表不要Id public partial class OrderAdress { public string Province { get; set; } public string City { get; set; } public string Zero { get…
「借鉴学习计划」的核心是:复制一份别人的学习计划到自己的计划中,并同步推送学习任务给自己,并且每个操作都要发送通知给对方. 它们的类图如下: 它们的关系是一对多: // Schedule entity.HasOne(x => x.Parent).WithMany(x => x.Children).HasForeignKey(x => x.ParentId).OnDelete(DeleteBehavior.Restrict); entity.HasIndex(nameof(Schedule…
1 前置阅读 在阅读本文章之前,你可以先阅读: 什么是DDD DDD的实体.值对象.聚合根的基类和接口:设计与实现 2 什么是仓储? 仓储封装了基础设施来提供查询和持久化聚合操作. 它们集中提供常见的数据访问功能,从而提供更好的可维护性,并将用于访问数据库的基础结构或技术与领域模型层分离. 创建数据访问层和应用程序的业务逻辑层之间的抽象层. 实现仓储可让你的应用程序对数据存储介质的更改不敏感. 3 为什么仓储? 直接访问数据: 重复的代码 难以集中化与数据相关的策略(例如缓存) 编程错误的可能性…
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板. ABP的官方网站:http://www.aspnetboilerplate.com ABP官方文档:http://www.aspnetboilerplate.com/Pages/Documents Github上的开源项目:http…
本次DDD实践选取我们都熟悉的高校成绩管理作为例子. (一).需求描述 每学期学校教务处老师会进行教学安排,具体就是建立教学班,指定该教学班代课教师,上课学生,然后进行排课(忽略此部分,这是另一个系统).指定上课学生有下面几种方式:单独一个班上课:多个班合上课:一个班部分学生上课:一个班部分学生与其它班合上课.也有一些教学任务,上课学生是没有规律的,即我们熟悉的选修课,是由学生自由选择的. 学期末,代课教师会根据自己所授课程上课学生名单登记成绩,经教务处审核后该成绩即可公布.登记成绩时系统需要标…
1.在Util类库下新建DIService类 /// <summary> /// 创建一个类,对应在配置文件中配置的DIServices里面的对象的 key /// </summary> public class DIService { public string InterfaceType { get; set; } public string ImplementationType { get; set; } } 2 在webapi的appsettings.json文件中配置 要…
1.在Products解决方案文件夹下面新建一个项目 .net Core/Asp.net Core Web应用程序  取名Product.WebApi/选择Web Api core2.0版本 不进行身份验证 2.添加一个控制器(的API控制器). 3.这个webapi项目只依赖于AppSrv项目,所以添加引用 Product.AppSrv. 4.添加AddProduct接口方法 namespace Product.WebApi.Controllers { [Produces("applicati…
1.新建一个解决方案文件夹 取名Product 2.在Product解决方案文件夹下面创建一个.net core 类库项目 取名Product.Domain,引用项目DDD.Base项目 3.在类库下面新建一个文件夹 取名POCOModels,在这个文件夹下面新建两个partial的类 分别取名ProductSPU和ProductSKU 4.新建一个IProductContext的接口 /// <summary> /// 上下文接口,之所以创建这个接口是因为,在本例子中会使用EFCore的上下…