abp vnext2.0核心组件之DDD组件之实体结构源码解析

       接着abp vnext2.0核心组件之模块加载组件源码解析和abp vnext2.0核心组件之.Net Core默认DI组件切换到AutoFac源码解析集合.Net Core3.1,基本环境已经完备,接下去就是构建领域层,vnext整个领域层大致分为聚合根、实体、值对象、事件实体、仓储、服务等等,内容较多,所以我打算分随笔进行介绍.首先介绍领域实体。注:这边所说的实体,是abp团队提供的抽象.如果不了解领域相关的知识,建议阅读<<领域驱动设计:软件核心复杂性应对之道>>需要一定设计模式的功底.如果设计模式不了解,请移步本人的设计模式分类.我也是略懂,所以本文有不当之处,请指正!谢谢!另外提一点,贫血的领域模型和充血的领域模型有本质的区别.有兴趣的可以研究研究,后续有时间我也会补充随笔,大家一起来探讨.

 

领域实体分为审计实体和一般实体,如下图所示

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第1张图片

 图中红框为常用实体抽象,Events中的实体需要配和EventBus事件总线,这一块作为vnext的单独组件,后续我会写一篇文章解析源码.ok,下面开始讲解.

 

整个实体抽象结构和老版abp没有什么大的区别.单单从内容看.首先介绍普通实体.分为聚合根和一般实体

1、实体

为什么要先介绍实体,因为聚合根也是一个实体,实体代码如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第2张图片

 abp vnext2.0核心组件之DDD组件之实体结构源码解析_第3张图片

 这边就很有趣了,很明显支持复合主键的实体.貌似和老版Abp不一样,记不太清了,一般情况下,复合主键的设计也比较少见.单主键较多.

再看看泛型实体,主键可自行指定

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第4张图片

 很简单,这边说下Equals的逻辑,比较复杂,如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第5张图片

 这两个逻辑很简单,看看就明白了.

接下去判断实体的主键

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第6张图片

 如果主键的值为其类型的默认值,且比较的两个类型都是如此,那么直接认为两个实体不相等.

到这里需要理解下这个逻辑,如果两个实体不为空,且类型一致,且引用不一样,但是两个实体的主键都为其类型的默认值.则认为两个实体不相等.

 官方解释是:Transient objects are not considered as equal

接着

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第7张图片

 两个类型必须具有类型的IS-a关系或必须是同一类型

接着

 如果两个实体都是租户实体,且上面的条件都不满足的情况下,两个实体的租户Id不相等,则认为两个实体不相等.

ok,实体结构到这里解析完毕,比较简单.

 

2、聚合根

聚合根本身也属于一个实体,其结构如下

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第8张图片

 挑几个核心接口解析下

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第9张图片

 每一个聚合根都具有一组方法来操作领域事件,因为领域事件作为vnext单独组件的存在,所以本文不做解析,后续会有随笔进行介绍.

接着

每一个聚合根都维护了一个额外属性的字段,方便进行灵活的扩展.比如和mogodb等库进行合作.

接着

 每一个聚合根都维护着一个并发令牌,初始化聚合根时,直接给一个GUID值,貌似只在EF Core中有效.其他ORM可能需要自行实现(个人理解,如果Dapper支持这种机制,请在评论区告知,万分感谢)。

当然对应的有一个泛型版本,主键可自行指定

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第10张图片

ok,整个聚合根的结构也介绍完毕,比较简单. 

 

3、审计实体 - 创建型实体

(1)、创建型实体

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第11张图片

 只包含创建功能的常规实体抽象.泛型版本主键可自行指定 如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第12张图片

 整个设计我个人有一个疑问,如下:

 主键不应当统一吗?欢迎在评论区讨论.

 

(2)、创建型实体带创建人抽象

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第13张图片

 如果当前记录需要记录创建人,那么就可以使用这个实体.当然也提供了泛型版本,主键可自行指定

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第14张图片

 

4、审计实体 - 创建修改型实体

(1)、创建修改型实体

如果当前实体同时具备创建和修改的功能,那么可以使用如下实体抽象

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第15张图片

 这里的Guid,依然如此,个人觉得主键需统一,泛型版本主键可自行指定 如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第16张图片

 

(2)、创建修改型实体呆创建者和修改者

如果当前实体同时具备创建和修改的功能,同时需要记录创建者和修改者,那么可以使用如下实体抽象

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第17张图片

 泛型版本,主键可自行指定 如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第18张图片

 

5、审计实体 - 创建修改删除型实体

(1)、创建修改删除型实体

如果当前记录具备创建、修改、删除三大功能,那么可以使用如下实体抽象

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第19张图片

 

 泛型版本 主键可自行指定 如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第20张图片

(2)、创建修改删除型实体带创建者和修改者和删除者

如果当前实体同时具备创建和修改和删除的功能,同时需要记录创建者和修改者和删除者,那么可以使用如下实体抽象

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第21张图片

  泛型版本 主键可自行指定 如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第22张图片

 

 

6、审计聚合根 - 创建型聚合根

如果当前聚合根具备创建的功能,那么可以使用如下实体抽象

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第23张图片

 泛型版本 主键自行指定如下

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第24张图片

 因为篇幅问题,聚合根其余的功能就不介绍了,和实体一致.其实本质聚合根就是一个实体.

ok,vnext关于DDD的实体结构架构大致就是如此,很简单,当然这边领域事件结构没有介绍,后续有随笔会介绍.可以看到,除了主键没有统一.这个设计非常的nice

 

7、值对象

关于值对象有如下文章

https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/implement-value-objects

微软提供的关于值对象的实现思路,abp团队也是参照此文章实现,其代码如下:

abp vnext2.0核心组件之DDD组件之实体结构源码解析_第25张图片

 

 abp vnext2.0核心组件之DDD组件之实体结构源码解析_第26张图片

 

 abp团队也只是提供了简单的抽象,代码也比较简单,这里就不多说明了.

 

纯属个人理解,能力有限,有问题请指正!

你可能感兴趣的:(abp vnext2.0核心组件之DDD组件之实体结构源码解析)