简介
在 .NET 项目里实践 DDD,最难的往往不是写一个聚合根,也不是引入 EF Core,而是把领域模型、应用编排、持久化、验证、事务、异常响应这些东西自然地接起来。
太轻了,团队会反复写样板代码;太重了,又容易被框架本身的约定和模块体系牵着走。
Dddify 想解决的正是这个中间地带:它不是一个大而全的应用框架,而是一个面向现代 ASP.NET Core 应用的轻量级 DDD 集成框架。它基于 MediatR、FluentValidation、Scrutor、Mapster 和 EF Core 等成熟生态,提供一组围绕 DDD 与 Clean Architecture 的基础能力,让团队把更多精力放在业务建模上。
Dddify 的定位
Dddify 的核心定位可以概括为一句话:
为 ASP.NET Core 项目提供轻量、可组合、贴近原生生态的 DDD 基础设施。
它推荐典型的四层结构:
text
Domain 领域模型、聚合、值对象、领域事件、仓储契约
Application 命令、查询、验证器、处理器、DTO、应用编排
Infrastructure EF Core、仓储实现、外部服务、迁移配置
Web HTTP 入口、启动配置、表现层模型
这种结构并不新鲜,但 Dddify 的价值在于:它把这套结构中最容易重复接线的部分封装好了,同时又没有强行接管整个应用。
它提供了什么
Dddify 内置了一组常用 DDD 基础类型,包括:
AggregateRoot<TKey>:聚合根基类Entity<TKey>:实体基类ValueObject:值对象基类IDomainEvent:领域事件契约IRepository<TEntity, TKey>:仓储契约DomainException/AppException:领域与应用异常- 审计、软删除、并发戳等接口与基类
在应用层,它通过 MediatR 组织命令和查询:
csharp
public record CreateTodoCommand(
string Title,
string? Description,
TodoPriority Priority,
DateTime? DueDate) : ICommand<Guid>;
命令处理器只负责编排用例:校验外部条件、创建或加载聚合、调用领域行为、保存结果。真正的业务规则仍然留在领域模型里。
在示例项目 TodoApp 中,Todo 聚合通过方法表达业务动作:
csharp
public void Complete(DateTime completedAt)
{
EnsureNotDeleted();
if (Status == TodoStatus.Completed)
{
return;
}
Status = TodoStatus.Completed;
CompletedAt = completedAt;
}
这比在 handler 里直接改状态更清晰,也更符合 DDD 对"不变量由聚合维护"的要求。
应用层:命令、查询、验证和工作单元
Dddify 默认集成了两个非常实用的 MediatR 管道行为:
ValidationBehavior<,>:执行 FluentValidation 验证UnitOfWorkBehavior<,>:为命令请求提供工作单元与事务边界
这意味着应用层可以写得很干净。比如创建 Todo 时,验证器负责请求级规则:
csharp
public class CreateTodoCommandValidator : AbstractValidator<CreateTodoCommand>
{
public CreateTodoCommandValidator()
{
RuleFor(c => c.Title)
.NotEmpty()
.MaximumLength(Todo.TitleMaxLength);
RuleFor(c => c.Priority)
.NotNull()
.IsInEnum();
}
}
handler 则负责编排:
csharp
public async Task<Guid> Handle(CreateTodoCommand command, CancellationToken cancellationToken)
{
if (await todoRepository.AnyAsync(c => c.Title == command.Title, cancellationToken))
{
throw new TodoTitleDuplicateException(command.Title);
}
var todo = new Todo(
guidGenerator.Create(),
command.Title,
command.Description,
command.Priority,
command.DueDate);
await todoRepository.AddAsync(todo, cancellationToken);
return todo.Id;
}
保存和事务不需要每个 handler 手写。启用 AddDbContextWithUnitOfWork<TContext>() 后,写命令会自动进入工作单元管道。
EF Core 集成:不只是注册 DbContext
Dddify 对 EF Core 的集成不只是帮你注册一个 DbContext。它还提供:
- 工作单元
- 仓储基类
- 保存拦截器
- 审计字段自动填充
- 软删除转换
- 并发戳刷新
- 领域事件分发
- 分页、条件查询等查询扩展
典型配置非常直接:
csharp
builder.Services.AddDddify(cfg =>
{
cfg.AddDbContextWithUnitOfWork<ApplicationDbContext>(options =>
{
options.UseSqlite(builder.Configuration.GetConnectionString("Default"));
});
});
在 DbContext 中可以应用默认约定:
csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
modelBuilder.ApplyDefaultConventions();
base.OnModelCreating(modelBuilder);
}
这样,软删除、并发戳等约定就可以跟领域接口自然衔接起来。
统一 API 响应与异常映射
对 Web API 项目来说,Dddify 还提供了 API 结果包装能力:
csharp
builder.Services.AddDddify(cfg =>
{
cfg.AddApiResultWrapping();
});
启用后,成功响应、业务异常、验证异常、并发冲突和未知异常都可以转换为统一结构:
json
{
"success": false,
"errorCode": "todo_title_duplicate",
"errorMessage": "todo_title_duplicate",
"traceId": "..."
}
这对前后端协作很友好。业务异常可以通过稳定错误码表达问题,错误码也可以作为本地化资源 key。
轻量,但不是简陋
Dddify 的一个重要取舍是:它保留 ASP.NET Core 原生组合方式。
它不会强制你使用某个项目模板,不接管认证授权,不绑定 UI,不要求复杂模块系统。你仍然可以按项目实际情况选择 Razor Pages、Web API、Minimal API,或者已有的基础设施。
它更像是一套"DDD 落地工具箱":
- 你需要领域建模,它给你聚合、实体、值对象、领域事件。
- 你需要应用编排,它给你命令、查询、处理器和管道行为。
- 你需要持久化,它给你 EF Core 工作单元和仓储基类。
- 你需要工程规范,它帮你减少重复接线。
- 你想保留灵活性,它不强行把项目塞进一个巨大的框架体系。
适合什么项目
Dddify 特别适合这些场景:
- 中小型 ASP.NET Core 业务系统
- 业务逻辑复杂的单体应用
- 希望实践 DDD 但不想引入重型框架的团队
- 已有项目想渐进式引入命令、查询、工作单元和领域事件
- 业务规则会持续演进,需要清晰领域边界的系统
如果你的项目需要完整的多租户、权限、后台管理、模块市场和预构建业务模块,ABP 这类完整框架可能更合适。
但如果你想要的是"保留 ASP.NET Core 原生体验,同时少写一堆基础设施代码",Dddify 的方向就很舒服。
从 TodoApp 看落地方式
仓库中的 TodoApp 示例展示了完整的四层实践:
text
TodoApp.Domain
TodoApp.Application
TodoApp.Infrastructure
TodoApp.Web
它围绕一个 Todo 聚合展开,包含:
- 聚合建模
- 命令和查询
- DTO
- FluentValidation 验证器
- 领域事件
- EF Core + SQLite 持久化
- Razor Pages UI
示例刻意保持小而聚焦。它不是为了炫技,而是为了让你快速看懂:Dddify 希望项目代码如何分层、如何流动、如何把业务规则放回领域模型。
生态延伸:Dddify Admin
除了核心框架和 TodoApp 示例,Dddify 官方还提供了配套的中后台项目:https://github.com/esofar/dddify-admin。
Dddify Admin 基于 Dddify 与 Ant Design Pro 构建,面向真实企业后台场景,提供更完整的工程化实践,目前仍在持续开发中。
相比偏入门示例的 TodoApp,Dddify Admin 更接近真实项目开发,也体现了 Dddify 从基础框架向业务系统脚手架的生态延伸。
总结
Dddify 的价值,不在于发明一套全新的架构概念,而在于把 .NET 生态里成熟的工具,以 DDD 和 Clean Architecture 的方式组织起来。
它让你不用从零搭建:
- MediatR 注册
- FluentValidation 管道
- Mapster 配置
- Scrutor 扫描
- EF Core 工作单元
- 领域事件分发
- 审计与软删除
- API 响应包装
同时,它又足够克制,不会替你决定整个应用应该长什么样。
对于想在 ASP.NET Core 中认真落地 DDD 的团队来说,Dddify 是一个很有亲和力的起点:轻量、清晰、贴近原生生态,也足够务实。
鸣谢
Dddify 在设计和实现过程中参考了社区中多个优秀开源项目的实践经验,特别感谢:
这些项目在 .NET 领域建模、应用分层、CQRS、基础设施组织和 Clean Architecture 实践方面都提供了很有价值的参考。