Files
Yi.Framework/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/01.依赖关系.md

89 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
大家好呀~ 最近我这里收到很多人的疑惑
- 从零开始我怎么手动分层依赖搭建一个项目
- 如果想依赖其他组件应该怎么引入
- 为什么要这样分层?和三层架构有什么区别?
- 等等
这些问题,很多初学者会疑惑的地方,就是照葫芦画苗,但是也说不出理由来,最后反而失去了这样分层的优势。
每一层都是有它的理由,明确了意义,在编码阶段才更得心应手,发挥出这样分层的作用。
> 题外话很是有缘在完全没有接触过DDD的分层的时候还是停留在三层架构的时期对于大型复杂的依赖关系Service满天飞根本难以下手写出的代码交错复杂稍微隔一段时间没去回顾再去看就会被自己的代码给绕死所以我就一直想换一种分层模式想让各个服务结构更加清晰不再是直肠子式的三层架构那我做的第一件事情就是把关系比较紧密的给装在一起当成一个整体各个整体之间不轻易去依赖而是通过事件去抛出去。这就在早期形成了一套依赖关系比较清晰的框架经过不断的项目历练慢慢的就变成了业务聚合、应用组装等等概念等到机会接触到了DDD分层一看`哇塞,怎么那么像?这怕不是他抄我的分层嘛`,当然开个玩笑,从此对这块的了解更加加深,确实值得很多大家应该学习的地方,提升一下自己。
> 一千个码农就有一千个DDD。DDD不一定完全是适合的并且DDD也从不是银弹但一定是值得学习使用的
> 在此,老橙子很乐意以我的血淋淋的教训的角度给大家讲清楚,框架的分层依赖关系,同时也是标准的`DDD分层架构`依赖关系,希望能给大家带来一些帮助~
## 依赖关系
这个标题其实已经在之前一个章节有涉及到一部分,`目录结构`,不过既然想弄清楚依赖关系,就得先了解目录结构,大家可以先回顾一下,弄清楚有哪些文件,再看它的依赖关系
![alt text](image-3.png)
从上至下,分别是
- 应用层
- 应用抽象层
- 领域层
- 领域共享层
- 基础设施ORM层
- Host主机
对应的项目引用关系下图所示:
![alt text](image-2.png)
可以从上图很直观的看出:
最顶层的`host主机与下面的应用`没有关系意味着host主机可以是web、可以是cs等等。所以我们的host主机只充当一个web启动的作用不包含业务逻辑
另外发现目录中只包含ORM好像没有基础设施层其实是一个包含关系是ORM属于基础设施中的一种但是为了将orm抽象特意把ORM独立了一层
由于框架的基础设施都已经在Framework里面包含所以没有单独建立一层新的基础设施层你完全可以`再加一层`在ORM下当作基础设施即可。
> web应用中对数据库操作涉及非常广所以ABP将ORM特意抽象出来可实现EFCore、MongoDb等数据库无缝切换。
## 每层的内容
- **基础设施层**存放各种通用方法、ORM等
- **领域共享层**存放枚举、常量、事件参数、对应用层的dto
- **领域层**存放业务的内部实现领域服务、领域事件。对外也就是对应用层可以暴露实体、对应用层的dto
- **应用抽象层**存放应用层抽象、系统对外的dto
- **应用层**存放对业务的组装领域服务对外暴露的dto主要是对外的用户交互相关的业务
- **Host主机**存放跟WebHost类似web启动器包括中间件、swagger、等与web相关
## 为什么要这样分层?
弄清楚了分层结构,已经依赖关系,我们可以探究里面的原理,我们为什么要这样做?这样做的道理或者好处是什么?
### 基础设施层
首先,不管是任何系统,想要对通用方法的复用,就必然有基础设施供整个系统的使用。这个`基础设施层`其实就类似于三层架构的`Common层`,这个没啥说的
这一层目的是为了通用方法的复用
### 领域层
领域,这个词经常出现,感觉很抽象,我们可以把他类比成`盒子`或者`模块`,比如电商系统的售前、售后,我们这可以分成两个大的`领域`
这里是整个结构的业务实现在这块,也是最重的一层。严格来说,不同领域之间想要调用,比如售后领域想查看售前领域的记录,可以通过事件抛出来,从而各个领域之间没有强耦合。
这一层的作用是实现各个领域的业务
### 领域共享层
这里只是存放一些领域所要使用的枚举、常量等,除了基础设施不要有其他的依赖,轻、也轻越好,因为他的目的不是对内,而是提供给给外部系统使用的。
这一层的作用是存放共享的枚举、常量等也是为了存放领域层暴露给应用层的dto比如领域层想暴露一个用户角色菜单对象实体无法满足就需可以创建这样的一个dto了在其他文章可能大家会叫做info对象
### 应用层
领域层是对内的外部系统是不清楚的那我们的业务实现想暴露出去要通过应用层进行包装因为应用层是对外的对用户交互相关处理比如api、signalr等
这一层的目的是对领域层的组装及数据的效验、对外用户交互相关处理。
### 应用抽象层
这里主要目的是将应用层暴露进行抽象,该层是为了提供外部系统之间依赖,于`领域共享层`类似,所以这一层也非常的轻,从上面的依赖关系图来看,`领域共享层``应用抽象层`是一条线性依赖。
这一层目的是为了`应用抽象层`可以被外部系统之间引用从而通过Http代理等技术实现远程调用接口访问`应用层`进行交互。这里感兴趣的可以看一下Abp.VNext的HttpProxy模块默认意框架中不引入等有需要的时候可以使用。
## 小结
以上分层是DDD推荐的一种最佳实践方式之一很荣幸通过我十几个上线项目应用情况事实证明非常nice
补充一句话我不是DDD的崇拜者只是在被各种业务折磨的不行的码农想追求一种方法让花更少的时间更好的去完成任务。
所以,我的内容是比较偏向实践,正如意框架一般,一个追求以用户体验为中心的框架。
意框架很多地方并没有完全严格走DDD包括Abp等有名的框架过于严格代码体验感反而是下降。有很多场景其实是没有必要的过长的代码、过绕的领域关系写个增删改查还得花很多时间这也是为什么DDD难以被接受的原因之一。