7.3 KiB
7.3 KiB
你的任务是按照 *.instructions.md 描述的规范完成功能开发任务。
重要规则
- 优先遵循instructions文档描述的规范
最佳实践
- 优先使用主构造函数
- 使用各类组件时,优先使用await关键字,使用Async方法
根据需要按照下列顺序完成工作
- 定义聚合、实体
- 定义领域事件
- 创建仓储接口与仓储实现
- 配置实体映射
- 定义命令与命令处理器
- 定义查询与查询处理器
- 定义Endpoints
- 定义领域事件处理器
- 定义集成事件
- 定义集成事件转换器
- 定义集成事件处理器
项目结构
Fengling.Member.sln
├── src/
│ ├── Fengling.Member.Domain/ # 领域层 - 聚合根、实体、领域事件
│ ├── Fengling.Member.Infrastructure/ # 基础设施层 - EF配置、仓储接口、仓储实现
│ └── Fengling.Member.Web/ # 表现层 - API、应用服务
└── test/ # 测试项目
├── Fengling.Member.Domain.UnitTests/ # 领域层测试项目
├── Fengling.Member.Infrastructure.UnitTests/ # 基础设施层测试项目
└── Fengling.Member.Web.UnitTests/ # 表现层测试项目
分层依赖关系: Web → Infrastructure → Domain (严格单向依赖)
对于具体的开发工作,请参考以下详细指令文件:
聚合与领域层
- 聚合根开发: 参考
.github/instructions/aggregate.instructions.md - 领域事件定义: 参考
.github/instructions/domain-event.instructions.md
数据访问层
- 仓储实现: 参考
.github/instructions/repository.instructions.md - 实体配置: 参考
.github/instructions/entity-configuration.instructions.md - 数据库上下文: 参考
.github/instructions/dbcontext.instructions.md
应用服务层
- 命令处理: 参考
.github/instructions/command.instructions.md - 查询处理: 参考
.github/instructions/query.instructions.md - 领域事件处理: 参考
.github/instructions/domain-event-handler.instructions.md
API表现层
- API端点: 参考
.github/instructions/endpoint.instructions.md
集成事件处理
- 集成事件: 参考
.github/instructions/integration-event.instructions.md - 集成事件转换器: 参考
.github/instructions/integration-event-converter.instructions.md - 集成事件处理器: 参考
.github/instructions/integration-event-handler.instructions.md
测试
- 单元测试: 参考
.github/instructions/unit-testing.instructions.md
最佳实践
(遵循各模块对应的 *.instructions.md 文档;本节不再另行维护“通用最佳实践”文件以避免重复和漂移。)
核心开发原则
文件组织
- 聚合根 →
src/Fengling.Member.Domain/AggregatesModel/{AggregateFolder}/ - 领域事件 →
src/Fengling.Member.Domain/DomainEvents/ - 仓储 →
src/Fengling.Member.Infrastructure/Repositories/ - 实体配置 →
src/Fengling.Member.Infrastructure/EntityConfigurations/ - 命令与命令处理器 →
src/Fengling.Member.Web/Application/Commands/ - 查询与查询处理器 →
src/Fengling.Member.Web/Application/Queries/ - API端点 →
src/Fengling.Member.Web/Endpoints/ - 领域事件处理器 →
src/Fengling.Member.Web/Application/DomainEventHandlers/ - 集成事件 →
src/Fengling.Member.Web/Application/IntegrationEvents/ - 集成事件转换器 →
src/Fengling.Member.Web/Application/IntegrationEventConverters/ - 集成事件处理器 →
src/Fengling.Member.Web/Application/IntegrationEventHandlers/
强制性要求
- ✅ 所有聚合根使用强类型ID,且不手动赋值ID(依赖EF值生成器)
- ✅ 所有命令都要有对应的验证器
- ✅ 领域事件在聚合发生改变时发布,仅聚合和实体可以发出领域事件
- ✅ 遵循分层架构依赖关系 (Web → Infrastructure → Domain)
- ✅ 使用KnownException处理已知业务异常
- ✅ 命令处理器不调用SaveChanges(框架自动处理)
- ✅ 仓储必须使用异步方法(GetAsync、AddAsync等)
关键技术要求
- 验证器: 必须继承
AbstractValidator<T>而不是Validator<T> - 领域事件处理器: 实现
Handle()方法而不是HandleAsync() - FastEndpoints: 使用构造函数注入
IMediator,使用Send.OkAsync()和.AsResponseData();端点采用属性特性配置(如[HttpPost]、[AllowAnonymous]、[Tags]),不使用Configure() - 强类型ID: 直接使用类型,避免
.Value属性,依赖隐式转换 - 仓储: 通过构造函数参数访问
ApplicationDbContext,所有操作必须异步 - ID生成: 使用EF Core值生成器,聚合根构造函数不设置ID
异常处理原则
KnownException使用规范
在需要抛出业务异常的地方,必须使用 KnownException 而不是普通的 Exception:
正确示例:
// 在聚合根中
public void OrderPaid()
{
if (Paid)
{
throw new KnownException("Order has been paid");
}
// 业务逻辑...
}
// 在命令处理器中
public async Task<OrderId> Handle(OrderPaidCommand request, CancellationToken cancellationToken)
{
var order = await orderRepository.GetAsync(request.OrderId, cancellationToken) ??
throw new KnownException($"未找到订单,OrderId = {request.OrderId}");
order.OrderPaid();
return order.Id;
}
框架集成:
KnownException会被框架自动转换为合适的HTTP状态码- 异常消息会直接返回给客户端
- 支持本地化和错误码定制
常见using引用指南
GlobalUsings.cs配置
各层的常用引用已在GlobalUsings.cs中全局定义:
Web层 (src/Fengling.Member.Web/GlobalUsings.cs):
global using FluentValidation;- 验证器global using MediatR;- 命令处理器global using NetCorePal.Extensions.Primitives;- KnownException等global using FastEndpoints;- API端点global using NetCorePal.Extensions.Dto;- ResponseDataglobal using NetCorePal.Extensions.Domain;- 领域事件处理器
Infrastructure层 (src/Fengling.Member.Infrastructure/GlobalUsings.cs):
global using Microsoft.EntityFrameworkCore;- EF Coreglobal using Microsoft.EntityFrameworkCore.Metadata.Builders;- 实体配置global using NetCorePal.Extensions.Primitives;- 基础类型
Domain层 (src/Fengling.Member.Domain/GlobalUsings.cs):
global using NetCorePal.Extensions.Domain;- 领域基础类型global using NetCorePal.Extensions.Primitives;- 强类型ID等
Tests层 (test/*/GlobalUsings.cs):
global using Xunit;- 测试框架global using NetCorePal.Extensions.Primitives;- 测试中的异常处理
常见手动using引用
当GlobalUsings未覆盖时,需要手动添加:
查询处理器:
using Fengling.Member.Domain.AggregatesModel.{AggregateFolder};
using Fengling.Member.Infrastructure;
实体配置:
using Fengling.Member.Domain.AggregatesModel.{AggregateFolder};
端点:
using Fengling.Member.Domain.AggregatesModel.{AggregateFolder};
using Fengling.Member.Web.Application.Commands.{FeatureFolder};
using Fengling.Member.Web.Application.Queries.{FeatureFolder};