快速上手领域驱动设计:基于 Ncp.CleanDDD 的 .NET 架构模板实践
在现代软件开发中,领域驱动设计(Domain-Driven Design, DDD)已成为构建复杂业务系统的核心方法论。然而,DDD 概念抽象、分层繁多,初学者常因“不知如何落地”而望而却步。为降低 DDD 实践门槛,社区涌现出多个标准化架构模板,其中 Ncp.CleanDDD 作为一款轻量、规范且面向 .NET 开发者的开源项目,提供了开箱即用的 Clean Architecture + DDD 融合结构。
本文将带你全面了解 Ncp.CleanDDD 模板的设计理念、核心分层、关键组件,并演示如何快速创建一个符合 DDD 原则的 .NET 应用。
一、什么是 Ncp.CleanDDD?
Ncp.CleanDDD 是由国内开发者社区维护的一个 .NET 解决方案模板(GitHub 项目名通常为 Ncp.CleanDDD 或类似变体),它深度融合了:
- 领域驱动设计(DDD):聚焦业务核心,划分聚合、实体、值对象、领域服务等。
- 整洁架构(Clean Architecture):通过依赖倒置实现内外层解耦。
- CQRS 模式:命令与查询分离,提升可维护性与扩展性。
- MediatR、FluentValidation、EF Core 等主流库:提供现代化 .NET 开发体验。
💡 注:虽然 “Ncp.CleanDDD” 并非官方 Microsoft 项目,但其命名和结构代表了一类广泛采用的 DDD 实践模板(类似 Jason Taylor 的 CleanArchitecture 演进版)。本文以典型结构为准进行说明。
二、项目结构解析
典型的 Ncp.CleanDDD 解决方案包含以下核心项目(按依赖方向从内到外):
src/
├── MyProject.Domain ← 领域层(纯业务逻辑,无外部依赖)
├── MyProject.Application ← 应用层(用例、DTO、MediatR Handlers)
├── MyProject.Infrastructure ← 基础设施层(EF Core、邮件、文件存储等实现)
├── MyProject.WebApi ← 表示层(ASP.NET Core Web API)
tests/
├── MyProject.Application.UnitTests
├── MyProject.Domain.UnitTests
└── MyProject.IntegrationTests
1. Domain 层 —— 业务核心
- Entities / Aggregates:如
Order,Customer - Value Objects:如
Address,Money - Domain Events:如
OrderCreatedEvent - Interfaces:仓储接口(
IOrderRepository)、领域服务接口 - Enums / Exceptions:业务异常(
InsufficientBalanceException)
✅ 特点:零外部 NuGet 包依赖,100% 聚焦业务规则。
2. Application 层 —— 用例协调者
- Commands / Queries:使用 MediatR 定义操作(如
CreateOrderCommand) - DTOs:请求/响应模型(
CreateOrderRequest,OrderDto) - Validators:基于 FluentValidation 的输入校验
- Behaviors:管道行为(日志、事务、授权)
- Implementations:调用 Domain 层执行业务
✅ 特点:依赖 Domain,不依赖 Infrastructure 或 Web。
3. Infrastructure 层 —— 技术实现
- Persistence:EF Core DbContext、仓储实现
- Services:邮件发送、文件上传、第三方 API 封装
- Dependency Injection:注册所有服务(
AddInfrastructure扩展方法)
✅ 特点:实现 Domain 中定义的接口,完成“脏活”。
4. WebApi 层 —— 对外暴露
- Controllers:极薄,仅转发请求给 MediatR
- Program.cs:配置 DI、中间件、Swagger
- appsettings.json:配置管理
✅ 特点:可随时替换为 gRPC、Worker Service 或 Blazor Server。
三、关键代码示例
1. 定义聚合根(Domain)
// Domain/Orders/Order.cs
public class Order : AggregateRoot
{
public Guid CustomerId { get; private set; }
public DateTime CreatedAt { get; private set; }
public OrderStatus Status { get; private set; }
public static Order Create(Guid customerId)
{
var order = new Order
{
Id = Guid.NewGuid(),
CustomerId = customerId,
CreatedAt = DateTime.UtcNow,
Status = OrderStatus.Pending
};
order.AddDomainEvent(new OrderCreatedEvent(order.Id));
return order;
}
public void Approve() => Status = OrderStatus.Approved;
}
2. 应用层命令处理(Application)
// Application/Orders/CreateOrderCommand.cs
public record CreateOrderCommand(Guid CustomerId) : IRequest<Guid>;
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, Guid>
{
private readonly IOrderRepository _orderRepository;
private readonly IUnitOfWork _unitOfWork;
public CreateOrderCommandHandler(IOrderRepository orderRepository, IUnitOfWork unitOfWork)
{
_orderRepository = orderRepository;
_unitOfWork = unitOfWork;
}
public async Task<Guid> Handle(CreateOrderCommand request, CancellationToken ct)
{
var order = Order.Create(request.CustomerId);
await _orderRepository.AddAsync(order, ct);
await _unitOfWork.SaveChangesAsync(ct); // 提交事务
return order.Id;
}
}
3. 控制器(WebApi)
// WebApi/Controllers/OrdersController.cs
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IMediator _mediator;
public OrdersController(IMediator mediator) => _mediator = mediator;
[HttpPost]
public async Task<Guid> Create(CreateOrderCommand command)
=> await _mediator.Send(command);
}
四、为什么选择 Ncp.CleanDDD 类模板?
| 优势 | 说明 |
|---|---|
| ✅ 清晰分层 | 业务与技术分离,新人易上手 |
| ✅ 测试友好 | Domain 和 Application 可独立单元测试 |
| ✅ 演进灵活 | 可轻松替换数据库、消息队列或前端 |
| ✅ 社区成熟 | 基于大量实战经验,避免“纸上谈兵”式 DDD |
五、快速启动项目
-
克隆模板(假设存在 GitHub 仓库):
git clone https://github.com/your-org/Ncp.CleanDDD.Template.git MyProject cd MyProject dotnet new --install ./template/ dotnet new cleanddd -n MyECommerceApp -
或手动创建结构,参考 Jason Taylor 的 CleanArchitecture 并融入 DDD 聚合设计。
六、结语
Ncp.CleanDDD 不是一个框架,而是一种架构约定。它通过标准化项目结构,帮助团队聚焦领域建模,避免陷入“技术细节先行”的陷阱。对于中大型业务系统,采用此类模板可显著提升代码可维护性、团队协作效率和长期演进能力。
📌 建议:不要盲目套用所有概念。从小聚合开始,逐步引入领域事件、防腐层(ACL)、Saga 等高级模式。
通过 Ncp.CleanDDD 这样的模板,DDD 不再是“空中楼阁”,而是可落地、可迭代、可持续的工程实践。立即尝试,让你的 .NET 项目从“能跑”走向“优雅”。