模块架构最佳实践与规范
解决方案结构
- 务必为每个模块创建独立的Visual Studio解决方案
- 务必将解决方案命名为公司名.模块名(核心ABP模块采用Volo.Abp.模块名)
- 务必采用分层方式开发模块,包含多个相互关联的包(项目)
- 每个包都有独立的模块定义文件,并显式声明所依赖的包/模块
分层与包结构
下图展示了一个良好分层模块的包结构及其相互依赖关系:
最终目标是让应用程序能够灵活使用模块。示例应用场景:
A) 单体应用程序
- 引用Web和Application包
- 根据偏好引用EF Core或MongoDB包之一
- 结果:
- 应用程序可显示模块UI
- 在同一进程中托管应用层和领域层(因此需要引用数据库集成包)
- 同时提供模块的HTTP API服务(通过Web包包含HttpApi包)
B) 将模块作为微服务的应用程序
- 引用HttpApi和Application包
- 根据偏好引用EF Core或MongoDB包之一
- 结果:
- 应用程序无法显示模块UI(未引用Web包)
- 在同一进程中托管应用层和领域层
- 提供模块的HTTP API服务(作为主要目标)
C) 显示模块UI但不托管应用的应用程序(将其作为由应用A或B托管的远程服务使用)
- 引用Web和HttpApi.Client包
- 为HttpApi.Client包配置远程端点
- 结果:
- 应用程序可显示模块UI
- 不在同一进程中托管模块的应用层和领域层,而是作为远程服务使用
- 同时提供模块的HTTP API服务(通过Web包包含HttpApi包)
D) 仅将模块作为远程服务使用的客户端应用(或微服务)(由应用A、B或C托管)
- 引用HttpApi.Client包
- 为HttpApi.Client包配置远程端点
- 结果:
- 应用程序可作为远程客户端使用模块全部功能
- 仅作为客户端,无法提供模块的HTTP API服务
- 无法显示模块的UI
E) 托管模块HTTP API但仅将请求转发至其他应用的代理应用(由应用A、B或C托管)
- 引用HttpApi和HttpApi.Client包
- 为HttpApi.Client包配置远程端点
- 结果:
- 应用程序可作为远程客户端使用模块功能
- 提供模块的HTTP API服务,但实际上类似代理,将所有(模块相关)请求重定向到远程服务器
下一节将详细说明各包结构。
领域层
- 务必将领域层分为两个项目:
- Domain.Shared包(命名为公司名.模块名.Domain.Shared),包含常量、枚举等可安全共享给模块所有层的类型。该包也可共享给第三方客户端。不得包含实体、仓储、领域服务等业务对象
- Domain包(命名为公司名.模块名.Domain),包含实体、仓储接口、领域服务接口及实现等领域对象
- Domain包依赖Domain.Shared包
应用层
- 务必将应用层分为两个项目:
- Application.Contracts包(命名为公司名.模块名.Application.Contracts),包含应用服务接口及相关数据传输对象
- 应用契约包依赖Domain.Shared包
- Application包(命名为公司名.模块名.Application),包含应用服务实现
- 应用包依赖Domain和Application.Contracts包
- Application.Contracts包(命名为公司名.模块名.Application.Contracts),包含应用服务接口及相关数据传输对象
基础设施层
- 务必为每个ORM/数据库集成创建独立集成包(如Entity Framework Core和MongoDB)
- 例如创建公司名.模块名.EntityFrameworkCore包抽象EF Core集成。ORM集成包依赖Domain包
- 禁止让ORM/数据库集成包依赖其他层
- 务必为每个计划可替换的主要库创建独立集成包(确保不影响其他包)
HTTP层
- 务必创建HTTP API包(命名为公司名.模块名.HttpApi)开发REST风格HTTP API
- HTTP API包仅依赖Application.Contracts包,不依赖Application包
- 务必为每个应用服务创建控制器(通常通过实现其接口)。这些控制器使用应用服务接口委托操作,仅配置路由、HTTP方法等Web相关需求
- 务必创建HTTP API Client包(命名为公司名.模块名.HttpApi.Client)为HTTP API包提供客户端服务。这些客户端服务将应用接口实现为远程端点客户端
- HTTP API Client包仅依赖Application.Contracts包
- 务必使用ABP的动态HTTP C#客户端代理功能
Web层
- 务必创建Web包(命名为公司名.模块名.Web)包含页面、视图、脚本、样式、图像等UI组件
- Web包仅依赖HttpApi包
抠丁客



