fengling-member-service/.github/copilot-instructions.md

7.3 KiB
Raw Blame History

你的任务是按照 *.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; - 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未覆盖时需要手动添加

查询处理器:

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};