mcpField
D
dotnet-core

dotnet-core

github.com/alexander-danilenko开发1779 次安装5 天前更新
代码仓库

关于 dotnet-core

.NET 8 后端服务的架构规范技能,面向设计和维护服务的开发者。内容涵盖分层、领域模型、验证、可观测性与测试,并说明何时采用 CQRS 和 AOT。

主要功能

  1. 01依赖向内的分层架构
  2. 02实体工厂与不变量约束
  3. 03CQRS 与管道行为规范
  4. 04Minimal APIs 按功能分组
  5. 05健康检查与结构化日志
  6. 06集成测试与容器建议

适用场景

  1. 01规划 .NET 8 服务的项目结构
  2. 02审查领域层与基础设施边界
  3. 03统一验证和横切关注点处理
  4. 04设计服务健康检查与集成测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alexander-danilenko/cortex-ai-skills --skill dotnet-core

安装后在 Claude Code 中输入/dotnet-core确认已加载。

详细介绍

.NET Core 架构

.NET 8 后端服务的架构约定。本文介绍服务的_结构_;语言层面的约定请参阅 csharp 技能。

分层

依赖只能指向内层。领域层对其他所有内容一无所知,而基础设施层是唯一允许引用数据库或 SDK 的层——因此内层无需依赖这两者也能进行测试。

Domain          entities, value objects, domain events, interfaces  → no dependencies
Application     use cases, CQRS handlers, DTOs, validators          → Domain
Infrastructure  EF Core, external APIs, implementations of Domain interfaces → Domain + Application
Api             endpoints, DI wiring, middleware                    → all of the above

确保这一约定得到遵守的测试是:如果 Domain 除了 BCL 之外不依赖任何包就能编译,那么边界就是完整的。

实体负责维护自身的不变条件:使用私有 setter、为 EF Core 的物化器提供私有无参构造函数,以及负责验证的静态工厂。公开 setter 意味着任何层都能将实体置于无效状态;此时“领域保证 X”就只是一句注释。

public class Product
{
    public string Name { get; private set; } = string.Empty;
    public decimal Price { get; private set; }

    private Product() { } // EF Core materialisation only

    public static Product Create(string name, decimal price) =>
        price <= 0
            ? throw new DomainException("Price must be greater than zero")
            : new Product { Name = name, Price = price };
}

约定

  • 仅当读写确实存在差异时,才使用 MediatR 实现 CQRS——例如模型、数据一致性或扩展方式不同。对 CRUD 服务而言,这只是形式主义;应根据领域需求采用,而不是默认使用。
  • 横切关注点应放在管道行为中,而不是处理程序中。将验证、日志记录和事务一次性写入行为后,就能应用于每个处理程序,也不会在新增处理程序时遗漏。
  • 使用 MapGroup 对 Minimal API 进行分组,每个功能领域使用一个文件。Program.cs 集中放置所有端点时,路由数量达到约 20 个就会变得难以阅读。
  • 在 Application 边界进行验证(在行为中使用 FluentValidation),这样无论通过哪个入口点调用用例,都适用相同规则。只在端点进行验证,只能保护 HTTP 入口。
  • DbContext 应留在 Infrastructure 中,由 Application 层拥有的接口提供访问。将 DbContext 泄漏到处理程序中,会使你的用例绑定到 EF,并且无法在没有提供程序的情况下进行测试。
  • 绝不将密钥放入 appsettings.json——本地使用 user-secrets,生产环境使用环境变量或密钥库。任何已提交的密钥都已泄露;轮换密钥还意味着需要重新部署。
  • 从一开始就设置运行状况检查(/health/live、/health/ready)和带关联 ID 的结构化日志。在故障正在发生时才补充可观测性,不是发现自己毫无监控的好时机。务必让两个探针真正有所区别:就绪探针可以检查数据库和下游 API;存活探针只能检查进程本身是否存活。若存活探针 ping 数据库,数据库短暂抖动时就会重启每个 Pod,将可恢复的依赖故障变成全面中断。
  • 容器应以非 root 用户运行。 添加一行 USER——默认以 root 身份运行的容器会将进程级入侵扩大到主机级权限,而只需一行配置就能避免这种情况。
  • 使用 WebApplicationFactory 编写集成测试,并连接真实数据库(Testcontainers)。这类测试会覆盖 DI 依赖图、路由、序列化和 EF 映射——这些正是被模拟的单元测试会在服务已损坏时仍报告成功的层。
  • 只有在启动时间或占用空间确实有要求时才使用 AOT。 AOT 不支持运行时反射,这可能会悄无声息地破坏某些序列化器和 DI 模式;在决定采用之前,先验证整个技术栈都能兼容。

评论

支持 Markdown