惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
V
Visual Studio Blog
博客园 - 司徒正美
TaoSecurity Blog
TaoSecurity Blog
博客园 - 聂微东
IT之家
IT之家
博客园_首页
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - Franky
雷峰网
雷峰网
罗磊的独立博客
S
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
The Cloudflare Blog
T
Tailwind CSS Blog
B
Blog RSS Feed
H
Help Net Security
T
The Blog of Author Tim Ferriss
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
C
CERT Recently Published Vulnerability Notes
博客园 - 三生石上(FineUI控件)
P
Palo Alto Networks Blog
I
Intezer
G
GRAHAM CLULEY
Engineering at Meta
Engineering at Meta
S
Securelist
J
Java Code Geeks
V
V2EX
Y
Y Combinator Blog
Simon Willison's Weblog
Simon Willison's Weblog
L
LINUX DO - 热门话题
云风的 BLOG
云风的 BLOG
Spread Privacy
Spread Privacy
MongoDB | Blog
MongoDB | Blog
P
Privacy International News Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog
Forbes - Security
Forbes - Security
Google Online Security Blog
Google Online Security Blog
Help Net Security
Help Net Security
S
SegmentFault 最新的问题
N
Netflix TechBlog - Medium
Webroot Blog
Webroot Blog
Microsoft Security Blog
Microsoft Security Blog
SecWiki News
SecWiki News
Scott Helme
Scott Helme
aimingoo的专栏
aimingoo的专栏
N
News and Events Feed by Topic

博客园 - China Soft

.NET 程序保护实战系列01-流水线架构与保护引擎总览 试官问:你用 AI 编程半年了,那怎么保证 Claude Code 写出来的代码是对的? C#实现控制台多区域输出 园友特惠| 1Panel 企业版 & AI 一体机限量放售,最高直降 5100! 上位机程序发布打包成安装包---Inno Setup 这是一篇学习笔记,分享给大家,如果大家喜欢,也会开启USB的专辑 我问了 AI 一个问题:编码能力贬值后,什么能力值钱? Visual Studio 2026(VS2026) 密钥/激活码 C# ESP32/STM32 轻量 Web 能力库:PicoServer.Nano 高性能百度OCR ONNX Runtime C#实现 别再说 AI 开发就是调接口了!5 种主流模式一次讲清 使用Cursor实现管理系统登录界面的快速开发 在 Avalonia 中编写高性能动画 傻子可懂的 Harness Engineering 入门教程 + 项目实战,一次搞懂 AI 编程工程化! 提升 Text2SQL 准确率 AI/Vibe Coding,本质是软件人工时代向软件工业时代发展 体验优先:十分钟使用 Python+LangChain 玩转阿里通义千问 大模型基础(二):必懂5大基础概念《Token、上下文窗口、Embedding、预训练、微调》 大模型基础(一):什么是LLM? Prompt、Agent、Function Call、Skill、MCP,傻傻分不清楚? 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 作为一线研发,我快被全网的 AI 焦虑逼疯了。 Qt QtWebEngine 白屏的解决方案 都是微软亲儿子,WPF凭啥干不掉WinForm?这3个场景说明白了 .NET 高级开发 | C# 中的动态代码:反射、EMIT、表达式树、Roslyn、Source Generators 大模型看大模型:推理Token的能耗用电量比对 WorkBuddy:从“我是谁”到“帮我干活” .NET 高级开发 | 开发 .NET 诊断工具、链路追踪原理 Prompt 焚诀——一个模板,终结你和 AI 的所有沟通问题 [项目]涉案资产信息化管理平台(山东某执法单位定制开发) 大模型RAG实战,从被骂不靠谱到成为部门MVP,这是我的踩坑全记录 白帽子为什么几乎都绕不开 httpx:一款 HTTP 资产探测工具的技术价值 从Prompt工程到Skill工程:Agent Skills开放标准彻底改变了AI协作方式 MAUI项目在Android平台通过U盘实现软件更新 微软竟然出了免费的 AI 应用开发课?!我已经学上了 一文彻底搞懂 OpenClaw 的架构设计与运行原理(万字图文) AI到底聪明在哪——从手机人脸识别说起 硬核科普:为何小米任天堂封杀 Root?揭秘操作系统从启动到“夺权”的底层游戏
Dddify:给 ASP.NET Core 项目一套轻量、清晰、可落地的 DDD 基础设施
China Soft · 2026-05-19 · via 博客园 - China Soft

简介#

在 .NET 项目里实践 DDD,最难的往往不是写一个聚合根,也不是引入 EF Core,而是把领域模型、应用编排、持久化、验证、事务、异常响应这些东西自然地接起来。

太轻了,团队会反复写样板代码;太重了,又容易被框架本身的约定和模块体系牵着走。

Dddify 想解决的正是这个中间地带:它不是一个大而全的应用框架,而是一个面向现代 ASP.NET Core 应用的轻量级 DDD 集成框架。它基于 MediatR、FluentValidation、Scrutor、Mapster 和 EF Core 等成熟生态,提供一组围绕 DDD 与 Clean Architecture 的基础能力,让团队把更多精力放在业务建模上。

Dddify 的定位#

Dddify 的核心定位可以概括为一句话:

为 ASP.NET Core 项目提供轻量、可组合、贴近原生生态的 DDD 基础设施。

它推荐典型的四层结构:

Domain          领域模型、聚合、值对象、领域事件、仓储契约
Application     命令、查询、验证器、处理器、DTO、应用编排
Infrastructure  EF Core、仓储实现、外部服务、迁移配置
Web             HTTP 入口、启动配置、表现层模型

这种结构并不新鲜,但 Dddify 的价值在于:它把这套结构中最容易重复接线的部分封装好了,同时又没有强行接管整个应用。

它提供了什么#

Dddify 内置了一组常用 DDD 基础类型,包括:

  • AggregateRoot<TKey>:聚合根基类
  • Entity<TKey>:实体基类
  • ValueObject:值对象基类
  • IDomainEvent:领域事件契约
  • IRepository<TEntity, TKey>:仓储契约
  • DomainException / AppException:领域与应用异常
  • 审计、软删除、并发戳等接口与基类

在应用层,它通过 MediatR 组织命令和查询:

public record CreateTodoCommand(
    string Title,
    string? Description,
    TodoPriority Priority,
    DateTime? DueDate) : ICommand<Guid>;

命令处理器只负责编排用例:校验外部条件、创建或加载聚合、调用领域行为、保存结果。真正的业务规则仍然留在领域模型里。

在示例项目 TodoApp 中,Todo 聚合通过方法表达业务动作:

public void Complete(DateTime completedAt)
{
    EnsureNotDeleted();

    if (Status == TodoStatus.Completed)
    {
        return;
    }

    Status = TodoStatus.Completed;
    CompletedAt = completedAt;
}

这比在 handler 里直接改状态更清晰,也更符合 DDD 对“不变量由聚合维护”的要求。

应用层:命令、查询、验证和工作单元#

Dddify 默认集成了两个非常实用的 MediatR 管道行为:

  • ValidationBehavior<,>:执行 FluentValidation 验证
  • UnitOfWorkBehavior<,>:为命令请求提供工作单元与事务边界

这意味着应用层可以写得很干净。比如创建 Todo 时,验证器负责请求级规则:

public class CreateTodoCommandValidator : AbstractValidator<CreateTodoCommand>
{
    public CreateTodoCommandValidator()
    {
        RuleFor(c => c.Title)
            .NotEmpty()
            .MaximumLength(Todo.TitleMaxLength);

        RuleFor(c => c.Priority)
            .NotNull()
            .IsInEnum();
    }
}

handler 则负责编排:

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。它还提供:

  • 工作单元
  • 仓储基类
  • 保存拦截器
  • 审计字段自动填充
  • 软删除转换
  • 并发戳刷新
  • 领域事件分发
  • 分页、条件查询等查询扩展

典型配置非常直接:

builder.Services.AddDddify(cfg =>
{
    cfg.AddDbContextWithUnitOfWork<ApplicationDbContext>(options =>
    {
        options.UseSqlite(builder.Configuration.GetConnectionString("Default"));
    });
});

DbContext 中可以应用默认约定:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
    modelBuilder.ApplyDefaultConventions();

    base.OnModelCreating(modelBuilder);
}

这样,软删除、并发戳等约定就可以跟领域接口自然衔接起来。

统一 API 响应与异常映射#

对 Web API 项目来说,Dddify 还提供了 API 结果包装能力:

builder.Services.AddDddify(cfg =>
{
    cfg.AddApiResultWrapping();
});

启用后,成功响应、业务异常、验证异常、并发冲突和未知异常都可以转换为统一结构:

{
  "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 示例展示了完整的四层实践:

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 实践方面都提供了很有价值的参考。