校园一体化管理系统2.1、基于整洁四层架构 + DDD+CQRS 项目目录解读

发布时间:2026/7/20 22:29:06
校园一体化管理系统2.1、基于整洁四层架构 + DDD+CQRS 项目目录解读 校园SaaS系统基于整洁四层架构 DDDCQRS 项目目录完整解读最近两天在编写controller层代码时在实际编写代码过程中从最初的三层架构到DDD领域模型、再到DDDCQRS尝试在代码结构与后期业务发展间反复权衡本人科班出身也有过两年开发经验现在转职高中信息技术老师闲暇时编写代码处理一些业务问题对现在流行的框架结构也不甚了解最终决定尝试四层架构来完成这个完整的项目如果有什么建议或意见欢迎留言交流前言本文基于.NET 8 搭建校园管理SaaS系统SchoolSaas采用整洁四层架构Clean Architecture作为工程分层基底核心业务模块落地DDD领域驱动设计 CQRS读写职责分离模式拆分5个独立类库项目严格遵循依赖倒置原则外层依赖内层领域核心层不感知任何外部技术数据库、缓存、API、AOP。整套架构适配教务、分班、学籍、社团多业务模块兼顾单人快速开发与长期业务迭代维护解决传统三层Service臃肿、业务逻辑散落、读写代码耦合等痛点。目录结构解决方案 SchoolSaas (5 个项目) ├─ SchoolSaas.Api # Presentation 表现层API入口 │ ├─ Connected Services │ ├─ Properties │ ├─ 依赖项 │ ├─ Controllers # 接口控制器 │ ├─ Extensions # Web服务注册扩展 │ ├─ Filters # 全局过滤器鉴权、异常 │ ├─ Mappings # DTO对象映射 │ ├─ Middleware # 自定义中间件 │ ├─ appsettings.json │ ├─ Dockerfile │ ├─ Program.cs │ └─ SchoolSaas.Api.http │ ├─ SchoolSaas.Application # Application 应用层CQRS核心 │ ├─ 依赖项 │ ├─ Commands # CQRS 写命令 CommandHandler │ ├─ Dtos # 应用层输入输出DTO │ └─ Queries # CQRS 查询 QueryHandler │ ├─ SchoolSaas.Domain # Domain 领域层DDD核心 │ ├─ 依赖项 │ ├─ Aggregates # DDD聚合根 │ ├─ DomainExceptions # 领域业务异常 │ ├─ DomainServices # 领域服务跨聚合业务 │ ├─ Events # 领域事件 IDomainEvent │ ├─ IRepositories # 仓储抽象接口 │ ├─ Specifications # 规约模式 │ └─ ValueObjects # 值对象 │ ├─ SchoolSaas.Infrastructure # Infrastructure 基础设施层技术实现 │ ├─ 依赖项 │ ├─ Aspects # AOP拦截器AspectCore │ ├─ Cache # Redis缓存实现 │ ├─ CommonTools # 底层通用工具 │ ├─ Data # EF Core DbContext、实体映射 │ ├─ Events # 领域事件发布实现 │ └─ Repositories # 仓储接口实现类 │ └─ SchoolSaas.Shared # 公共共享层全局通用基础类型 ├─ 依赖项 ├─ Constants # 全局常量 ├─ Dtos # 通用基础DTO分页、统一返回体 ├─ Enums # 全局枚举 ├─ Exceptions # 异常基类 ├─ Extensions # 通用扩展方法 └─ Interfaces # 通用基础抽象接口一、整体解决方案分层与依赖规则解决方案共5个项目由外至内对应整洁四层架构公共共享层项目名称四层架构对应层依赖规则SchoolSaas.ApiPresentation 表现层最外层仅依赖Application、Shared禁止直接引用Domain、InfrastructureSchoolSaas.ApplicationApplication 应用层流程编排层依赖Infrastructure、Shared不直接操作数据库、缓存SchoolSaas.DomainDomain 领域核心层业务心脏仅依赖Shared无任何外部技术依赖纯业务模型SchoolSaas.InfrastructureInfrastructure 基础设施层技术实现层依赖Domain、Shared实现Domain定义的所有抽象接口SchoolSaas.Shared公共共享层通用基础类型零业务层依赖存放全局枚举、常量、通用DTO、基础异常标准依赖流向不可反向Api → Application → Infrastructure → Domain二、分层目录详细职责解读1. SchoolSaas.ApiPresentation 表现层核心定位HTTP接入入口仅做请求转发、轻量参数校验、DTO转换零业务逻辑。目录功能说明Controllers所有API控制器按业务模块二级分包分班/教务/学籍/社团接收前端请求转换DTO为Command/Query通过Mediator发送至应用层只做入参、出参包装。Filters全局请求过滤器身份鉴权过滤器、全局异常捕获过滤器、请求参数基础校验过滤器属于Web层面通用拦截。Middleware自定义中间件跨域、请求日志、流量监控、请求ID生成等Web管道增强逻辑。ExtensionsWeb服务注册扩展方法Program.cs中统一注册控制器、Swagger、跨域等Web组件。Mappings前端DTO与CQRS输入对象的映射配置分离转换逻辑简化Controller代码。appsettings.json / Dockerfile项目配置文件、容器部署脚本仅Web入口层持有环境配置。2. SchoolSaas.ApplicationApplication 应用层CQRS核心载体核心定位业务流程编排层使用CQRS分离读写不承载任何业务规则仅协调资源、事务、事件分发。目录功能说明Commands写操作载体CQRS命令新增/修改/删除类业务如AllocateClassCommand、SubmitHomeworkCommand配套同级CommandHandlers处理器负责加载聚合、调用领域服务、提交事务、发布领域事件。Queries读操作载体CQRS查询报表、列表、多维度统计如QueryClassHomeworkStat年级作业通报查询配套QueryHandlers查询处理器专门处理多表联查、数据导出、大屏统计完全隔离写逻辑。Dtos应用层专用输入输出DTO区分Command入参、Query返回报表DTO按业务上下文分包隔离前端展示结构。3. SchoolSaas.DomainDomain 领域层DDD核心核心定位纯业务建模层无任何第三方包、无数据库、无缓存依赖收拢全部业务约束、状态流转规则是整个系统的业务标准。目录功能说明AggregatesDDD聚合根每个业务边界唯一对外操作入口如ClassAggregate班级聚合、StudentAggregate学生聚合聚合内部封装所有业务行为新增学生、调整班级、提交作业内置业务校验私有属性禁止外部直接赋值杜绝贫血模型。ValueObjectsDDD值对象无唯一标识、不可变数据载体手机号PhoneVo、成绩ScoreVo、班级容量CapacityVo封装格式校验逻辑。DomainServices领域服务处理跨聚合复杂业务批量分班、年级成绩核算仅依赖聚合根不操作仓储、数据库。IRepositories仓储抽象接口仅定义数据读写契约IClassRepository、IStudentRepository数据库实现交给Infrastructure领域层不感知存储介质。Events领域事件IDomainEvent聚合状态变更时产生如StudentAllocatedEvent学生分班事件用于解耦异步后置动作通知、数据同步、报表更新。DomainExceptions业务专属异常ClassFullException班级名额已满、InvalidScoreException分数非法领域校验失败直接抛出。Specifications规约模式封装复杂业务查询条件复用领域筛选规则解耦复杂判断逻辑。4. SchoolSaas.InfrastructureInfrastructure 基础设施层核心定位所有外部技术实现层实现Domain定义的抽象接口隔离数据库、缓存、AOP、消息队列等第三方技术更换存储/中间件仅改动本层不影响业务。目录功能说明AspectsAspectCore AOP全局拦截器Redis缓存拦截器、全局日志拦截器、幂等拦截器、异常环绕拦截作用于Application层Handler横切通用能力不侵入领域代码。DataEF Core数据库核心SchoolDbContext上下文、实体与表映射配置、数据迁移脚本MySQL适配。Repositories仓储实现类实现Domain层IXXXRepository封装DbContext、自定义统计SQLQuery侧宽表查询全部写在此处。CacheRedis缓存实现封装分布式缓存读写逻辑实现Domain缓存抽象接口。Events领域事件发布实现进程内同步投递、RabbitMQ异步消息投递统一处理领域事件分发。CommonTools基础设施通用工具文件存储、加密、第三方HTTP接口调用等底层工具封装。5. SchoolSaas.Shared公共共享层核心定位全局通用基础类型供其余四层全部引用无业务逻辑消除重复代码。目录功能说明Enums全局业务枚举班级类型、学籍状态、作业状态Constants系统常量、缓存Key前缀、数据库固定参数Dtos通用基础DTO统一分页返回体、全局接口响应包装类Exceptions基础全局异常基类所有业务异常继承于此Extensions通用扩展方法字符串、日期、集合拓展Interfaces通用基础抽象缓存通用接口、消息基础接口三、DDD CQRS 完整代码执行流程以「教导处执行新生分班」接口为例完整链路贴合本项目目录结构1. 请求入口Api层前端HTTP请求 →ClassController→ 封装入参生成AllocateClassCommand调用IMediator.Send(cmd)[HttpPost(allocate)] public async TaskIActionResult Allocate(AllocateDto dto) { var cmd new AllocateClassCommand(dto.ClassId, dto.StudentIds); var result await _mediator.Send(cmd); return Ok(result); }2. AOP拦截增强Infrastructure.AspectsMediator分发Command后先经过全局AOP拦截器记录操作日志、捕获全局异常、校验操作权限无业务修改逻辑仅环绕增强。3. CQRS CommandHandler 流程编排Application.CommandsAllocateClassCommandHandler仅做协调不写业务规则注入IClassRepository、IStudentRepository加载班级、学生聚合注入ClassAllocateDomainService领域服务执行跨聚合分班逻辑调用领域服务修改聚合内部状态聚合自动执行业务校验通过IUnitOfWork开启事务仓储批量更新聚合事务提交后收集聚合产生的领域事件统一发布。4. DDD领域模型执行业务规则Domain领域服务ClassAllocateDomainService.AllocateStudents()协调班级、学生两个聚合聚合根ClassAggregate.AddStudent()内置名额容量校验、学生状态校验状态变更时新增StudentAllocatedEvent领域事件所有业务约束收拢在聚合/领域服务上层Handler无法绕过校验直接修改属性。5. 持久化实现Infrastructure.Repositories仓储实现类使用EF Core DbContext将聚合根实体持久化到MySQL数据库。6. 领域事件异步解耦Infrastructure.Events Application EventHandlers发布StudentAllocatedEvent后事件处理器异步执行后置动作同步更新学生学籍所属班级推送通知给对应班主任刷新班级人数统计缓存预生成分班报表数据。查询流程CQRS读写分离报表场景前端请求班级作业统计报表 → Controller生成QueryClassHomeworkStat→ QueryHandler → 直接调用仓储多表统计SQL返回扁平报表DTO完全不经过领域聚合、无事务、无业务校验逻辑读写链路彻底隔离报表查询不占用写库资源。四、本架构核心优势总结分层职责彻底隔离符合整洁架构依赖倒置业务Domain完全独立更换MySQL、Redis、消息队列仅修改Infrastructure核心业务代码无需改动。DDD领域模型保证业务规则统一所有校验、状态流转收敛在聚合根杜绝上层代码绕过业务规则修改数据多人协作不会出现业务逻辑不一致。CQRS读写分离解决报表臃肿问题写操作走Command领域模型复杂统计、导出报表走Query独立链路查询逻辑不污染核心业务代码适配校园海量作业、成绩、分班统计场景。AOP横切通用能力业务代码干净缓存、日志、异常、鉴权全部抽离到基础设施拦截器Handler、领域模型无冗余横切代码。分层可渐进落地避免过度设计简单模块公告、报修可仅使用四层基础分层不强制DDD聚合分班、成绩、作业核心模块完整落地DDDCQRS平衡开发效率与长期可维护性。单元测试友好Domain层无外部依赖可Mock仓储接口单独测试领域业务规则无需启动数据库、Web服务。