实现领域驱动设计 - 使用ABP框架 - 解决方案概览
.NET解决方案的分层
下图显示了使用ABP的 应用启动模板 创建的Visual Studio解决方案:

解决方案名称为问题跟踪,它由多个项目组成。通过考虑DDD原则以及开发和部署实践,该解决方案是分层的。下面的小节解释了解决方案中的项目
领域层
领域层分为2个项目
- IssueTracking.Domain 是基本的领域层,它包含前面介绍的所有构建块(实体、值对象、域服务、规范、存储库接口等)
- IssueTracking.Domain.Shared 是一个很单薄的项目,它包含一些属于领域层的类型,但与所有其他层共享。例如,它可能包含一些与领域对象相关的常量和枚举,但需要被其他层重用
应用层
应用层也分为2个项目
- IssueTracking.Application.Contracts 包含应用程序服务接口和这些接口使用的dto。这个项目可以被客户端应用程序共享(包括UI)
- IssueTracking.Application 是实现Contracts项目中定义的接口的基本应用程序层。
表示层
- IssueTracking.Web 是一个ASP.NET Core MVC / Razor Pages 应用程序, 这是唯一为应用程序和api服务的可执行应用程序
远程服务层
- IssueTracking.HttpApi 项目包含解决方案定义的HTTP接口。它通常包含MVC控制器和相关模型。因此,您可以在这个项目中编写HTTP接口。
- IssueTracking.HttpApi.Client 当您有一个需要使用HTTP接口的c#应用程序时,此项目是有用的。一旦客户端应用程序引用了这个项目,它就可以直接注入和使用应用程序服务。这得益于ABP框架的 动态c#客户端API代理系统
友情提示: There is a Console Application in the test folder of the solution,named IssueTracking.HttpApi.Client.ConsoleTestApp. It simply uses the IssueTracking.HttpApi.Client project to consume the APIs exposed by the application. It is just a demo application and you can safely delete it. You can even delete the IssueTracking.HttpApi.Client project if you think that you don't need to them.
基础设施层
在DDD实现中,您可能有一个单一的基础设施项目来实现所有的抽象和集成,或者您可能对每个依赖项有不同的项目
我们建议采取一种平衡的方法;为主要的基础设施依赖项(如 Entity Framework Core)创建单独的项目,为其他基础设施创建一个通用的基础设施项目
ABP的启动解决方案有两个 Entity Framework Core 集成项目
- IssueTracking.EntityFrameworkCore 它是EF Core的基本集成包。你的应用程序的DbContext,数据库映射,存储库的实现和其他EF Core相关的东西都在这里
- IssueTracking.EntityFrameworkCore.DbMigrations 是一个管理Code First数据库迁移的特殊项目。在这个项目中有一个单独的DbContext来跟踪迁移。除了需要创建一个新的数据库迁移或添加一个具有一些数据库表的 应用程序模块 并自然需要创建一个新的数据库迁移外,您通常不会过多地涉及这个项目
你可能想知道为什么 EF Core 会有两个项目。它主要与 模块化 有关。每个模块都有自己独立的DbContext,应用程序也有一个DbContext。DbMigrations项目包含一个模块的联合,用于跟踪和应用单个迁移路径。虽然大多数时候你不需要知道它,但你可以查看 EF Core迁移文档 以获得更多信息
其他项目
还有一个项目,IssueTracking.DbMigrator,这是一个简单的控制台应用程序,它执行迁移数据库和 播种 初始数据。这是一个有用的实用程序应用程序,您可以在开发环境和生产环境中使用它。
解决方案中项目的依赖关系
下图显示了解决方案(IssueTracking)中项目之间的基本依赖关系(项目引用)。IssueTracking部分因为简单没显示)

这些项目之前已经解释过了。现在,我们可以解释依赖关系的原因
- Domain.Shared 是所有其他项目直接或间接依赖的项目。此项目里的所有类型均可被其他项目使用。
- Domain 只依赖 Domain.Shared。因为它已经是领域共享的一部分。例如,Domain.Shared 中的 IssueType 枚举 可以被 Domain 项目中的 Issue 实体使用
- Application.Contracts 依赖 Domain.Shared。通过这种方式,您可以在dto中重用这些共享的类型。比如, 在Domain.Shared中的IssueType 枚举 可以作为 CreateIssueDto 的一个属性
- Application 依赖 Application.Contracts 。因为它实现了应用程序服务接口并使用其中的dto。它还依赖于 Domain,因为应用程序服务被实现为使用在领域层中定义的领域对象
- EntityFrameworkCore 依赖 Domain。因为它将领域对象(实体和值类型)映射到数据库表(因为它是一个ORM),并实现领域中定义的存储库接口
- HttpApi 依赖 Application.Contracts。 因为它里面的 controller 会注入和使用应用服务接口
- HttpApi.Client 依赖 Application.Contracts。因为它可以像前面解释的那样使用应用程序服务
- Web 依赖 HttpApi。因为它提供在其内部定义的HTTP接口。而且,通过这种方式,它间接地依赖于 Application.Contracts 项目, 来使用页面/组件中的应用程序服务
基于DDD的应用程序的执行流程
下图显示了基于DDD模式开发的web应用程序的典型请求流

- 请求通常从UI上的用户交互(用例)开始,该用户交互导致向服务器发出HTTP请求
- 表现层(或分布式服务层)中的MVC控制器或Razor页面处理程序处理请求,并可以在此阶段执行一些横切关注点(授权、验证、异常处理等)。控制器/页面注入相关的应用程序服务接口,并通过发送和接收dto调用其方法
- 应用程序服务使用领域对象(实体、存储库接口、领域服务等)来实现用例。应用层实现一些横切关注点(授权、验证等)。应用程序服务方法应该是一个工作单元。这意味着它应该是原子的。
- 大多数横切关注点都是由ABP框架自动且常规地实现的,通常不需要为它们编写代码
实现领域驱动设计 - 使用ABP框架 - 解决方案概览的更多相关文章
- 实现领域驱动设计 - 使用ABP框架 - 什么是领域驱动设计?
前言: 最近看到ABP官网的一本电子书,感觉写的很好,翻译出来,一起学习下 (Implementing Domain Driven Design) https://abp.io/books DDD简介 ...
- 实现领域驱动设计 - 使用ABP框架 - 通用准则
在进入细节之前,让我们看看一些总体的 DDD 原则 数据库提供者 / ORM 无关性 领域和应用程序层应该与 ORM / 数据库提供程序 无关.它们应该只依赖于 Repository 接口,而 Rep ...
- 实现领域驱动设计 - 使用ABP框架 - 存储库
存储库 Repository 是一个类似于集合的接口,领域层和应用程序层使用它来访问数据持久性系统(数据库),以读写业务对象(通常是聚合) 常见的存储库原则是: 在领域层定义一个存储库接口(因为它被用 ...
- 实现领域驱动设计 - 使用ABP框架 - 创建实体
用例演示 - 创建实体 本节将演示一些示例用例并讨论可选场景. 创建实体 从实体/聚合根类创建对象是实体生命周期的第一步.聚合/聚合根规则和最佳实践部分建议为Entity类创建一个主构造函数,以保证创 ...
- .net core +codefirst(.net core 基础入门,适合这方面的小白阅读) 【我们一起写框架】领域驱动设计的CodeFirst框架(一)—序篇
.net core +codefirst(.net core 基础入门,适合这方面的小白阅读) 前言 .net core mvc和 .net mvc开发很相似,比如 视图-模型-控制器结构.所以. ...
- 【我们一起写框架】领域驱动设计的CodeFirst框架(一)—序篇
前言 领域驱动设计,其实已经是一个很古老的概念了,但它的复杂度依旧让学习的人头疼不已. 互联网关于领域驱动的文章有很多,每一篇写的都很好,理解领域驱动设计的人都看的懂. 不过,这些文章对于那些初学者而 ...
- 【DDD】使用领域驱动设计思想实现业务系统
最近新接了一个业务系统——社区服务系统,为了快速熟悉和梳理老系统的业务逻辑和代码,同时对老系统代码做一些优化,于是打算花上一个月时间不间断地对老系统服务进行重构.同时,考虑到社区业务的复杂性,想起了之 ...
- 基于ABP落地领域驱动设计-01.全景图
什么是领域驱动设计? 领域驱动设计(简称:DDD)是一种针对复杂需求的软件开发方法.将软件实现与不断发展的模型联系起来,专注于核心领域逻辑,而不是基础设施细节.DDD适用于复杂领域和大规模应用,而不是 ...
- 基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则
目录 前言 聚合 聚合和聚合根原则 包含业务原则 单个单元原则 事务边界原则 可序列化原则 聚合和聚合根最佳实践 只通过ID引用其他聚合 用于 EF Core 和 关系型数据库 保持聚合根足够小 聚合 ...
随机推荐
- MongoDB 集群-主从复制(一主二从)
MongoDB 集群-主从复制(一主二从) 官方文档 https://docs.mongodb.com/manual/tutorial/deploy-replica-set/ https://docs ...
- QT的MYSQL驱动库编译
QT的MYSQL驱动库编译 需要准备QT的源码Src,此次编译64位 在QTCreator中打开mysql.pro 修改两个pro 文件,下图为改好 1.mysql.pro TARGET = qsql ...
- Service vs Factory vs provider的迷惑
刚开始我很迷惑的,但是经过一段时间的项目,还有看大漠老师的东西,似乎明白了,他们的区别也就是 一个人喜欢吃面还是吃饭或者肯德基区别.目的就是填饱肚子! 以下是它们在AngularJS源代码中的定义: ...
- 2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组)
2021.12.10 P2516 [HAOI2010]最长公共子序列(动态规划+滚动数组) https://www.luogu.com.cn/problem/P2516 题意: 给定字符串 \(S\) ...
- docker基础_docker引擎内部原理
docker引擎内部原理 docker主要由以下主要组件构成:docker客户端.docker守护进程(daemon).containerd.runc.shim daemon daemon的主要功能包 ...
- Halo 开源项目学习(五):评论与点赞
基本介绍 博客系统中,用户浏览文章时可以在文章下方发表自己的观点,与博主或其他用户进行互动,也可以为喜欢的文章点赞.下面我们一起分析一下 Halo 项目中评论和点赞功能的实现过程. 发表评论 评论可以 ...
- Linux操作系统基本知识
1.Linux开发环境 2.GCC 2.1GCC工作流程 预处理:只运行 C 预编译器. 宏去掉了,注释没有了 汇编 编译 链接 2.2GCC常用参数选择 选项 解释 -ansi 只支持 ANSI 标 ...
- 团队Arpha5
队名:观光队 组长博客 作业博客 组员实践情况 王耀鑫 **过去两天完成了哪些任务 ** 文字/口头描述 完成服务器连接数据库部分代码 展示GitHub当日代码/文档签入记录 接下来的计划 服务器网络 ...
- Ping原理详解
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 前言 Ping是排除设备访问故障的常见方法.它使用Internet控制消息协议ICMP(Int ...
- css自定义省略实例1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...