你的任务是按照 *.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` 而不是 `Validator` - **领域事件处理器**: 实现 `Handle()` 方法而不是 `HandleAsync()` - **FastEndpoints**: 使用构造函数注入 `IMediator`,使用 `Send.OkAsync()` 和 `.AsResponseData()`;端点采用属性特性配置(如 `[HttpPost]`、`[AllowAnonymous]`、`[Tags]`),不使用 `Configure()` - **强类型ID**: 直接使用类型,避免 `.Value` 属性,依赖隐式转换 - **仓储**: 通过构造函数参数访问 `ApplicationDbContext`,所有操作必须异步 - **ID生成**: 使用EF Core值生成器,聚合根构造函数不设置ID ## 异常处理原则 ### KnownException使用规范 在需要抛出业务异常的地方,必须使用 `KnownException` 而不是普通的 `Exception`: **正确示例:** ```csharp // 在聚合根中 public void OrderPaid() { if (Paid) { throw new KnownException("Order has been paid"); } // 业务逻辑... } // 在命令处理器中 public async Task 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;` - ResponseData - `global using NetCorePal.Extensions.Domain;` - 领域事件处理器 **Infrastructure层** (`src/Fengling.Member.Infrastructure/GlobalUsings.cs`): - `global using Microsoft.EntityFrameworkCore;` - EF Core - `global 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未覆盖时,需要手动添加: **查询处理器**: ```csharp using Fengling.Member.Domain.AggregatesModel.{AggregateFolder}; using Fengling.Member.Infrastructure; ``` **实体配置**: ```csharp using Fengling.Member.Domain.AggregatesModel.{AggregateFolder}; ``` **端点**: ```csharp using Fengling.Member.Domain.AggregatesModel.{AggregateFolder}; using Fengling.Member.Web.Application.Commands.{FeatureFolder}; using Fengling.Member.Web.Application.Queries.{FeatureFolder}; ```