实现领域驱动设计 - 使用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 和 关系型数据库 保持聚合根足够小 聚合 ...
随机推荐
- SMBIOS- DMTF组织指定的规范
SMBIOS(System Management BIOS , SMBIOS) 是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范 SMBIOS是由行业指导机构Desktop Manage ...
- CVE 公开披露的网络安全漏洞列表
CVE®是一份公开披露的网络安全漏洞列表, 官方地址为 : https://cve.mitre.org/cve/ 比如 mavenrepository 上阿里的Druid修复的漏洞的列表如下:
- random模块、os模块、序列化模块、sy模块s、subprocess模块
random随机数模块 random.random( ) 随机产生一个0-1之间的小数 print(random.random()) # 0.31595547439342897 random.rand ...
- 发布nuget包的正确姿势---cicd自动打包发布nuget包
最轻便的发布nuget包方式,方便cicd自动打包发布nuget包 首先新建项目 项目名随便取,这里就叫它GuiH.ClassLibrary 默认即可,需要改目标版本时,等创建好再改 项目创建好了 随 ...
- Promise的then和catch如何影响状态的变化
记住两句话: 1.then正常返回resolved,里面有报错返回reject 1 const p1 = Promise.resolve().then(()=>{ 2 console.log(1 ...
- JS_进阶-遍历对象属性、数组输出、Math、正则表达式匹配
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...
- 使用 GO-CQHttp或mirai框架 搭建QQ的机器人
我的博客 Go-CQHttp搭建QQ机器人 官方文档在这-->ATRU官方文档 Go-CQHttp + Atri 使用Linux系统部署 需求 服务器一台/带有Linux的机器 Python环境 ...
- 漏洞复现:使用Kali制作木马程序
漏洞复现:使用Kali制作木马程序 攻击机:Kali2019 靶机:Win7 64位 攻击步骤: 1.打开Kali2019和Win7 64位虚拟机,确定IP地址在一个网段 2.确定好IP地址,进入Ka ...
- Linux系统常用命令速查手册
点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 系统信息 arch #显示机器的处理器架构(1 ...
- Android添加背景图片和设置app图标
Android添加背景图片和设置app图标 Android 添加背景图片 第一步:找到你要当做背景的图片,并下载下来 第二步:将图片复制到app->res->mipmap文件夹下 第三步: ...