在我较早的时候,就开始研究和介绍ABP框架,ABP框架相对一些其他的框架,它整合了很多.net core的新技术和相关应用场景,虽然最早开始ABP框架是基于.net framework,后来也全部转向拥抱.net core,而另一条线的ABP VNext则是定位从.net core开始的,基础类库以Volo.Abp开始。ABP框架和ABP VNext框架两者在基类和分层上,都很多几乎是一样的,不过ABP VNext框架是后来者,规避了很多前辈ABP框架的一些缺点,最明显的就是更加模块化(弊端就是管理的独立项目暴增),不过对于大项目来说,功能模块的切分也是必要的。ABP VNext是一个内容很丰富的架构体系,因此准备做一个系列介绍ABP VNext相关架构的知识,本篇随笔介绍它的一些框架基础类继承关系。

1、ABP VNext技术概述

ABP VNext框架如果不考虑在微服务上的应用,其集成使用的难度会降低一个层级,不过ABP VNext和ABP框架一样,基础内容都会设计很多内容,如数据库都支持Oracle、SQLServer、MySql、PostgreSQL、SQLite,都有利用Redis作为分布式缓存,使用RabbitMQ作为事件总线的消息处理方式,使用MongoDB的NoSQL类型数据库作为特殊数据的存储服务,使用Quartz/HangFire作为定时任务的处理等。如果考虑引入微服务的话,会更需要了解IdentityServer服务,以及了解Ocelot库管理网关,使用 Elasticsearch & Kibana 来存储和可视化日志 (使用Serilog写日志),有时候感觉引入框架并非一件轻松的事情,各种知识点一股脑的涌来。

我们开发复杂的系统,也是和建筑工人一样,一步步盖起房子来的,不同的是,有些人一块砖一块砖的盖,有些人采用预构件来构建,我们回到孩童的时候的思路,就是搭建积木的方式。

ABP VNext框架沿袭这种好习惯,把一些都简单化了,做起大项目来就更加方便了,类似搞一个乐高积木项目一样,不过我们约定了每个项目的基础分层部分,这样一来组装就标准化了。

如下面的一个项目,也可以当成它就是一个模块,和一个麻雀一样,五脏俱全,各个项目代表不同的功能,大家都这样做即可。

应用服务层:

Application.Contracts,包含应用服务接口和相关的数据传输对象(DTO)。
Application,包含应用服务实现,依赖于 Domain 包和 Application.Contracts 包。

领域层:
Domain.Shared,包含常量,枚举和其他类型.
Domain 包含实体, 仓储接口,领域服务接口及其实现和其他领域对象,依赖于 Domain.Shared 包.

基础设施层:

EntityFrameworkCore,包含EF的ORM处理,使用仓储模式,实现数据的存储功能。

HTTP 层
HttpApi项目, 为模块开发REST风格的HTTP API。
HttpApi.Client项目,它将应用服务接口实现远程端点的客户端调用,提供的动态代理HTTP C#客户端的功能。

各个层的依赖关系如下图所示。

我们把这些项目组成一个模块,即使这个模块只有一个表的处理功能,也是一个模块,它们构建成一个完整的模块内部生态层。

这样我们在以模块为基础单位,就可以单独开发,统一整合了,如下图所示。

这样,我们以相关的模块组合,以及一些辅助工具,就构成了整套框架的一个生态基础。

针对ABP VNext的前后端完全分离模式,我们给BS的前端,只需要提供API服务,以及接入详细说明即可,而给Winform、WPF、Console等基于.net的终端,则可以利用HTTP层的HttpApi.Client项目的动态客户端方式,避免编写API的客户端代理即可。

我详细参考了ABP VNext的基础框架类,以及一些应用模块项目的代码,它们基本上是提供了很多底层的支持,上层模块的支持,很多是在其商业版中的功能,并没有出现在应用模块中,如我们常见的权限系统的实现,它模块里面只是提供了简单的的角色和用户信息管理(而且很不完善),而我们往往需要扩展开来实现详细的用户、组织机构、角色、岗位、菜单、权限等功能的管理,才能算是一个完整的权限系统,另外还需要封装字典模块、附件管理模块等一些基础模块应用,这些就需要我们自己实现它的功能了。

以权限管理模块为例,它们虽然提供及基础的DTO和领域对象,没有提供完整应用层的实现,作为一个完整的应用系统,肯定不行,需要利用框架进一步实现才可以整合在项目中使用。

2、框架基础类继承关系

前面介绍了,本篇随笔作为系列的开篇,主要想介绍一下ABP VNext框架的一些基础类关系。

ABP VNext和ABP框架的基础类,虽然它们在项目管理上有所不同,不过它们的类关系层次继承关系,几乎没有太多的变化,有些一些层次上的调整而已。因此对于学习ABP或者ABP VNext框架来说,它们很多地方是共通的。

对于Application层来说,它是承接UI和领域层的中间层,因此它接收用户DTO对象,并且这些DTO对象为了和领域层的Entity层有映射关系,我们定义了一些基础类关系来协助它们,以方便DTO和Entity层之间的Mapping映射关系,从而通过约定方式承载系统的基础属性。

如ApplicationService层的相关DTO基类对象定义及继承关系如下图所示,其中右边是它们继承的接口,以及接口需要实现的属性信息。

注:上图ABP和ABP VNext框架,它们的基类定义和关系都是一样的。

而应用层有时候,需要对数据进行分页,并返回列表记录,那么下面的一些基类对象就是它的应用场景,通过定义分页信息和排序信息,可以让应用服务层获得相应的记录过滤,然后返回基于特定DTO对象的泛型列表,如下图所示。

注:上图ABP和ABP VNext框架,它们的基类定义和关系都是一样的。

ABP VNext框架的应用服务层类,提供了相关CRUD操作的基类,虽然我们有时候可以继承顶层ApplicationService进行开发,但是,为了方便,我们往往使用子类继承自CrudAppService,如下图所示。

首先定义相关自定义接口

  1. public interface IBookAppService :
  2. ICrudAppService< //定义CRUD方法
  3. BookDto, //显示DTO
  4. Guid, //实体主键
  5. PagedAndSortedResultRequestDto, //用于分页排序获取列表
  6. CreateUpdateBookDto, //创建对象DTO
  7. CreateUpdateBookDto> //更新对象DTO
  8. {
  9. }

然后实现该接口即可,如下所示。

  1. public class BookAppService :
  2. CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto,CreateUpdateBookDto, CreateUpdateBookDto>,
  3. IBookAppService
  4. {
  5. public BookAppService(IRepository<Book, Guid> repository)
  6. : base(repository)
  7. {
  8. }
  9. }

CrudAppService实现了ICrudAppService接口中声明的所有方法. 然后,你可以添加自己的自定义方法或覆盖和自定义实现.

相对于ABP VNext的应用服务层基类,它们ABP框架的基类有所差异 ,它们分离了同步和异步的基类,不过基本上都使用异步基类居多,继承关系图如下所示。

它的服务层接口定义和接口实现的处理方式和ABP VNext的操作类似,就不再赘述了。

相对于前面介绍DTO层的基类定义,我们在框架的领域层也定义了类似的类和它的继承关系,和DTO一一对应,这样通过AutoMapping 的方式就可以自动处理他们的属性映射了,减少了很多繁琐的代码处理。

领域层的实体类关系和前面DTO关系类似,如下所示。

"聚合是域驱动设计中的一种模式.DDD的聚合是一组可以作为一个单元处理的域对象.例如,订单及订单系列的商品,这些是独立的对象,但将订单(连同订单系列的商品)视为一个聚合通常是很有用的。

如果是聚合根,如商品、订单和订单明细的关系场景,就可以应用到,ABP不强制你使用聚合根,实际上你可以使用上面定义的Entity类。

它们和领域的实体关系整合起来是一张关系图,如下所示。

这个在基类部分,和ABP框架有所差异,ABP VNext框架中的聚合根增加了扩展属性的接口定义和实现,以及领域事件的处理接口,如下所示。

它们的部分基类代码如下所示

  1. namespace Volo.Abp.Domain.Entities
  2. {
  3. [Serializable]
  4. public abstract class AggregateRoot : BasicAggregateRoot,
  5. IHasExtraProperties,
  6. IHasConcurrencyStamp
  7. {
  8. public virtual ExtraPropertyDictionary ExtraProperties { get; protected set; }
  9.  
  10. [DisableAuditing]
  11. public virtual string ConcurrencyStamp { get; set; }
  12.  
  13. protected AggregateRoot()
  14. {
  15. ConcurrencyStamp = Guid.NewGuid().ToString("N");
  16. ExtraProperties = new ExtraPropertyDictionary();
  17. this.SetDefaultsForExtraProperties();
  18. }
  19.  
  20. public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
  21. {
  22. return ExtensibleObjectValidator.GetValidationErrors(
  23. this,
  24. validationContext
  25. );
  26. }
  27. }

而ABP 框架的聚合根部分,除了基类有所差异,处理一些特殊的信息外,基本上也是类似的。

以上就是ABP VNext的一些基类和关系图,希望能够促进我们了解ABP VNext框架的神秘之处,解开它的面纱。

如果你对ABP框架的知识点有兴趣,可以参考《ABP框架使用》,如果对于ABP框架VUE&Element前端开发有兴趣,可以参考《循序渐进VUE+Element》部分内容。

ABP VNext框架基础知识介绍(1)--框架基础类继承关系的更多相关文章

  1. ABP VNext框架基础知识介绍(2)--微服务的网关

    ABP VNext框架如果不考虑在微服务上的应用,也就是开发单体应用解决方案,虽然也是模块化开发,但其集成使用的难度会降低一个层级,不过ABP VNext和ABP框架一样,基础内容都会设计很多内容,如 ...

  2. Django框架基础知识07-常用查询及表关系的实现

    1.常用的模型字段类型 https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types 2.字段的常用参数 官方文档:http ...

  3. 4-1 Spring框架基础知识

    Spring框架基础知识 1.Spring 框架作用 主要解决了创建对象和管理对象的问题. 自动装配机制 2.Spring 框架 (Spring容器,JavaBean容器,Bean容器,Spring容 ...

  4. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

  5. PHP面试(二):程序设计、框架基础知识、算法与数据结构、高并发解决方案类

    一.程序设计 1.设计功能系统——数据表设计.数据表创建语句.连接数据库的方式.编码能力 二.框架基础知识 1.MVC框架基本原理——原理.常见框架.单一入口的工作原理.模板引擎的理解 2.常见框架的 ...

  6. DDD框架基础知识

    DDD框架基础知识 参考: https://www.cnblogs.com/zhili/p/OnlineStorewithDDD.html(领域驱动设计,分层架构) https://www.cnblo ...

  7. Nginx基础知识介绍

    Nginx基础知识介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Nginx概述 Nginx是免费的.开源的.高性能的HTTP和正向/反向代理服务器.邮件代理服务器.以及T ...

  8. TCP_Wrappers基础知识介绍

    1. TCP_Wrappers基础知识介绍 TCP_Wrappers是在 Solaris, HP_UX以及 Linux中广泛流行的免费软件.它被设计为一个介于外来服务请求和系统服务回应的中间处理软件. ...

  9. Swift Playgrounds for mac基础知识介绍

    Swift Playgrounds是一款适用于iPad和Mac的革命性应用程序,它使Swift学习变得互动而有趣.它不需要编码知识,因此非常适合刚开始的学生.使用Swift解决难题,以掌握基本知识.S ...

随机推荐

  1. 菜鸡的Java笔记 - java 双向一对多映射

    双向一对多映射    two-way    开发要求:        根据数据表的结构进行简单java类的转换:        要求实现如下的输出信息:            可以根据课程取得全部参与 ...

  2. Spring中常用注解

    1.@Component 创建类对象,相当于配置<bean/> 2.@Service @Service与@Component功能相同,写在ServiceImpl类上 3.@Reposito ...

  3. JS中bind、call和apply的作用以及在TS装饰器中的用法

    目录 1,前言 1,call 1.1,例子 1.2,直接调用 1.3,将this指向另一个对象 1.4,传递参数 2,apply 2.1,例子 2.2,直接调用 2.3,将this指向另一个对象 2. ...

  4. [loj6033]棋盘游戏

    将棋盘黑白染色,即构成一张二分图 将状态用一张二分图$G$和一个点$x\in V$描述(分别为仍未被经过的点的导出子图和当前棋子所在位置),并称将要移动棋子的一方为先手 结论:先手必胜当且仅当$x$一 ...

  5. [cf1479D]Odd Mineral Resource

    先考虑判定是否有解,注意到无解即每一个数都出现偶数次,根据异或的性质,只需要随机$V_{i}$,假设$u$到$v$路径上所有节点构成集合$S$,若$\bigoplus_{x\in S,l\le a_{ ...

  6. [atARC109E]1D Reversi Builder

    归纳每一次操作后必然是两个颜色相同的连续段(即ww...bb...或bb...ww...),对操作的位置分类讨论不难证明正确性 当$c_{1}=c_{n}$,由于端点颜色不会修改,再根据该结论,可以得 ...

  7. 【Sass/SCSS】我花4小时整理了的Sass的函数

    [Sass/SCSS]我花4小时整理了的Sass的函数 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 Sass 定义了各 ...

  8. Codeforces 1511G - Chips on a Board(01trie/倍增)

    Codeforces 题面传送门 & 洛谷题面传送门 一道名副其实的 hot tea 首先显然可以发现这俩人在玩 Nim 游戏,因此对于一个 \(c_i\in[l,r]\) 其 SG 值就是 ...

  9. Codeforces 1500E - Subset Trick(线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 一道线段树的套路题(似乎 ycx 会做这道题?orzorz!!11) 首先考虑什么样的 \(x\) 是"不合适"的,我 ...

  10. MySQL 数据库的下载、安装和测试

    实例:Ubuntu 20.04 安装 mysql-server_5.7.31-1ubuntu18.04_amd64.deb-bundle.tar 1. 下载安装MySQL(安装 MySQL 5.7) ...