何时使用
在编写后端项目时,如Aspire/Asp.Net Core WebAPI及其他与后端相关的内容。
Perigon分层结构
src/
├── Definition/
│ ├── Entity/ # 实体定义(按模块分文件夹)
│ ├── EntityFramework/ # EF DbContext 和迁移
│ ├── Share/ # 共享常量、扩展、服务
│ └── ServiceDefaults/ # 服务注册和中间件
├── Modules/
│ └── {ModuleName}/
│ ├── Managers/ # 业务逻辑层
│ └── Models/ # DTO 定义(按实体分文件夹)
│ └── Services/ # 模块内服务(可选)
└── Services/
├── ApiService/ # 公共 API
├── AdminService/ # 管理后台 API
└── MigrationService/ # 数据库迁移服务
Share共享项目
- •Shared constants live in src/Definition/Share/Constants; module-specific constants stay in their module/service.
- •Extend AppConst via extension methods in Share/Constants (e.g., AppExtensions) rather than modifying base constants.
多租户
架构支持多租户,也支持单租户,从AppHost的appsettings.Development.json配置中,可以知道当前是单租户还是多租户模式。
如果是单租户模式,tenantId默认为Guid.Empty。
模块依赖层次(从下到上)
- •Entity → 定义数据模型
- •EntityFramework → 配置 DbContext,依赖 Entity
- •Share + ServiceDefaults → 共享工具和服务注册,依赖 EntityFramework
- •Modules → 业务逻辑和 DTO,依赖 Entity 和 Share
- •Services → API 控制器,依赖 Modules
禁止:
- •❌ Manager 之间直接调用(通过共享服务或事件解耦)
- •❌ Controller 绕过 Manager 直接访问 DbContext
- •❌ Entity 包含业务逻辑(仅数据模型和验证注解)
- •❌ 不要面向接口编程。没有多个实现类的服务,不要为其创建接口。
开发流程
- •先处理定义层,即实体的定义,DbContext的处理,以及共享服务的编写
- •然后处理模块层,即Manager和DTO的编写
- •最后处理服务层,即Controller的编写
- •执行构建验证(必须步骤):验证编译无错误
- •检查项目依赖关系,确保没有违反分层原则
- •没有错误,添加或修改了实体,需要执行
scripts/EFMigrations.ps1脚本,生成迁移文件。
要优先使用MCP工具Perigon,生成或创建模块/Entity/DTO/Manager/Controller等内容。
构建验证(每次修改后必须执行)
验证后端服务
# 验证具体服务 dotnet build src/Services/AdminService dotnet build src/Services/ApiService # 验证业务模块 dotnet build src/Modules/AIAgentMod # 验证整个方案(推荐) dotnet build AIAgent.slnx
常见构建错误及解决
- •命名空间错误:检查 using 指令和 GlobalUsings.cs
- •符号未找到:检查依赖项引用和 NuGet 包
- •EF Core 错误:执行
dotnet ef migrations add生成迁移 - •版本冲突:检查 Directory.Packages.props 中的包版本
构建-修复循环
修改代码 → 构建 → 发现错误 → 修复 → 重新构建,直到无错误
MCP server config lives in .mcp.json and .vscode/mcp.json; use configured endpoints when invoking tools.
开发规范
错误处理
- •业务错误:抛出
BusinessException - •第三方服务调用:保留在
Share/Services中
DTO(数据传输对象)
通过MCP工具生成Dto,然后以此为模板再根据实际需求调整。
Manager
通过MCP工具生成Manager,然后以此为模板再根据实际需求调整。
如果Manager没有绑定特定的实体,则继承ManagerBase.cs的其他基类。
EF Core 查询,要使用方法调用,而不是使用 LINQ 查询语法。
对象映射
优先使用Perigon.AspNetCore.Utils.Extensions 中的扩展方法Merge/MapTo进行映射。
控制器(Controllers)
通过MCP工具生成Controller,然后以此为模板再根据实际需求调整。
如果Controller没有绑定特定的Manager,则继承RestControllerBase的其他基类。
✗ 避免:
- •直接访问 DbContext
- •实现业务逻辑
- •ApiResponse 包装器(使用标准响应)
返回值
- •成功:
ActionResult<T>直接返回模型 - •错误:使用
Problem()或NotFound() - •参数绑定:有歧义时使用显式特性
[FromBody]/[FromQuery]/[FromRoute]
Aspire / AppHost
可参考微软官方文档以实现相关的需求。 优先使用Aspire生态提供的功能和中间件。
代码约定
C# 14 语言特性
- •使用文件作用域命名空间
- •使用主构造函数
- •使用集合表达式
异步编程
- •全程异步:使用
async/await - •传递 Token:从 Controller 向 Manager/数据访问传递
CancellationToken
依赖注入
- •使用构造函数注入(Constructor Injection)
- •✗ 避免服务定位器模式
验证和业务规则
- •API 边界:验证输入参数
- •业务逻辑:验证规则保留在 Manager 中