项目

模块架构最佳实践与规范

解决方案结构

  • 务必为每个模块创建独立的Visual Studio解决方案
  • 务必将解决方案命名为公司名.模块名(核心ABP模块采用Volo.Abp.模块名
  • 务必采用分层方式开发模块,包含多个相互关联的包(项目)
    • 每个包都有独立的模块定义文件,并显式声明所依赖的包/模块

分层与包结构

下图展示了一个良好分层模块的包结构及其相互依赖关系:

模块分层与包结构

最终目标是让应用程序能够灵活使用模块。示例应用场景:

  • A) 单体应用程序

    • 引用WebApplication
    • 根据偏好引用EF CoreMongoDB包之一
    • 结果:
      • 应用程序可显示模块UI
      • 同一进程中托管应用层领域层(因此需要引用数据库集成包)
      • 同时提供模块的HTTP API服务(通过Web包包含HttpApi包)
  • B) 将模块作为微服务的应用程序

    • 引用HttpApiApplication
    • 根据偏好引用EF CoreMongoDB包之一
    • 结果:
      • 应用程序无法显示模块UI(未引用Web包)
      • 同一进程中托管应用层领域层
      • 提供模块的HTTP API服务(作为主要目标)
  • C) 显示模块UI但不托管应用的应用程序(将其作为由应用A或B托管的远程服务使用)

    • 引用WebHttpApi.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托管)

    • 引用HttpApiHttpApi.Client
    • 为HttpApi.Client包配置远程端点
    • 结果:
      • 应用程序可作为远程客户端使用模块功能
      • 提供模块的HTTP API服务,但实际上类似代理,将所有(模块相关)请求重定向到远程服务器

下一节将详细说明各包结构。

领域层

  • 务必将领域层分为两个项目:
    • Domain.Shared包(命名为公司名.模块名.Domain.Shared),包含常量、枚举等可安全共享给模块所有层的类型。该包也可共享给第三方客户端。不得包含实体、仓储、领域服务等业务对象
    • Domain包(命名为公司名.模块名.Domain),包含实体、仓储接口、领域服务接口及实现等领域对象
      • Domain包依赖Domain.Shared

应用层

  • 务必将应用层分为两个项目:
    • Application.Contracts包(命名为公司名.模块名.Application.Contracts),包含应用服务接口及相关数据传输对象
      • 应用契约包依赖Domain.Shared
    • Application包(命名为公司名.模块名.Application),包含应用服务实现
      • 应用包依赖DomainApplication.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
在本文档中