ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SlimMessageBus实现DDD领域事件:MessageBus.Current静态访问器与聚合根事件发布实战

SlimMessageBus实现DDD领域事件:MessageBus.Current静态访问器与聚合根事件发布实战 SlimMessageBus实现DDD领域事件MessageBus.Current静态访问器与聚合根事件发布实战【免费下载链接】SlimMessageBusLightweight message bus interface for .NET (pub/sub and request-response) with transport plugins for popular message brokers.项目地址: https://gitcode.com/gh_mirrors/sl/SlimMessageBusSlimMessageBus是 .NET 生态中的轻量级消息总线Lightweight Message Bus支持发布/订阅Pub/Sub与请求/响应Request/Response两种模式。本文以官方 DDD 示例为蓝本手把手演示如何用 SlimMessageBus 实现DDD 领域事件聚合根在状态变更后通过MessageBus.Current静态访问器发布事件由进程内的 Memory 传输直接分发给事件处理器——全程无需任何外部消息中间件5 分钟即可跑通。SlimMessageBus 领域事件的发布订阅架构一个主题承载多种消息类型一、为什么用消息总线实现领域事件在 DDD领域驱动设计中聚合根状态变更后需要通知审计、物流、通知等多个模块。传统的直接调用会让领域层耦合越来越多的旁观者而领域事件将发生了什么与谁来处理彻底解耦。用消息总线做领域事件有三个好处解耦聚合根只管发布完全不知道有哪些处理器一对多广播同一条事件可以同时被多个IConsumer订阅处理可替换传输今天用进程内 Memory明天换成 RabbitMQ / Kafka 只改配置不改业务代码官方文档对这个用例的描述见 docs/UseCases/DomainEvents.md完整可运行示例在src/Samples/Sample.DomainEvents.WebApi、src/Samples/Sample.DomainEvents.Domain、src/Samples/Sample.DomainEvents.Application三个项目中。二、MessageBus.Current 静态访问器的工作原理2.1 解决什么问题领域模型聚合根通常不依赖 DI 容器怎么拿到IMessageBusSlimMessageBus 的答案是一个静态入口——MessageBus.Current定义在src/SlimMessageBus/MessageBus.cs第 19 行public static IMessageBus Current _provider();它的核心机制是Current不是单例而是当前执行上下文的代理。SetProvider第 14 行注册一个解析函数由宿主插件按运行环境决定返回什么实例ASP.NET 场景下AddAspNet()插件让它返回当前 Web 请求作用域的IMessageBus消费消息时它返回当前正在处理的消息作用域的实例底层基于AsyncLocal绑定到任务Task因此async/await跨线程时作用域也不会丢失2.2 作用域意味着什么事件发布会加入正在进行的作用域Web 请求作用域或消息处理作用域。也就是说在请求里发布的事件其处理器与你的业务代码共享同一个 DI Scope可以直接注入仓储、日志等服务——这是进程内领域事件能保持事务一致性的关键。三、聚合根实战三行代码发布领域事件3.1 定义领域事件一个 POCO 即可领域事件就是最简单的 POCO示例中src/Samples/Sample.DomainEvents.Domain/OrderSubmittedEvent.cs仅 7 行public record OrderSubmittedEvent(Order Order) { public DateTime Timestamp { get; } DateTime.UtcNow; }3.2 聚合根内发布事件打开示例聚合根src/Samples/Sample.DomainEvents.Domain/Order.cs提交订单的逻辑只有两行核心代码第 37-43 行public async Task Submit() { State OrderState.Submitted; // 1. 变更领域状态 var e new OrderSubmittedEvent(this); await MessageBus.Current.Publish(e); // 2. 发布领域事件 }注意Submit()是async方法——Memory 传输默认阻塞式发布事件处理器执行完才返回这样await order.Submit()返回时所有领域事件处理器已经执行完毕业务语义最清晰。3.3 事件处理器实现 IConsumer处理器实现IConsumerT接口即可被发现示例见src/Samples/Sample.DomainEvents.Application/DomainEventHandlers/OrderSubmittedHandler.cspublic class OrderSubmittedHandler : IConsumerOrderSubmittedEvent { public Task OnHandle(OrderSubmittedEvent e, CancellationToken ct) { // 记录审计日志、生成物流单…… } }处理器从 DI 容器按作用域解析可以随意注入ILogger等依赖。四、最快配置方法Memory 传输 ASP.NET 插件整个 Web 项目只需一处注册见src/Samples/Sample.DomainEvents.WebApi/Startup.cs第 40-46 行services.AddSlimMessageBus(mbb { mbb.WithProviderMemory() // 进程内传输 .AutoDeclareFromAssemblyContainingOrderSubmittedHandler() // 自动扫描声明消费者 .AddAspNet(); // 让 MessageBus.Current 感知 Web 请求作用域 }); services.AddHttpContextAccessor(); // AspNet 插件的必需依赖三个配置点各管一件事配置作用WithProviderMemory()使用进程内传输零外部依赖AutoDeclareFromAssemblyContainingT()反射扫描程序集自动声明所有IConsumerT消费者AddAspNet()让MessageBus.Current绑定到当前 Web 请求作用域 需要跨进程、持久化或高吞吐时把WithProviderMemory()换成 RabbitMQ、Kafka、Azure Service Bus 等官方传输插件即可业务代码一行不改。五、完整调用链从 HTTP 请求到事件分发以src/Samples/Sample.DomainEvents.WebApi/Controllers/OrdersController.cs的下单接口为例整条链路非常直观POST /api/orders → new Order(customer) 创建聚合根 → order.Add(...) 添加订单行 → await order.Submit() 聚合根发布 OrderSubmittedEvent → MessageBus.Current.Publish(...) Web 请求作用域内 → OrderSubmittedHandler.OnHandle(...) 执行审计/日志 → return Ok() 此时事件处理器已全部执行完毕SlimMessageBus 的管道还支持在任意环节插入拦截器例如审计日志、重试策略、FluentValidation 校验等整体管道示意如下六、新手避坑清单 ✅忘记AddHttpContextAccessor()——AddAspNet()依赖它注入 HTTP 上下文漏掉后MessageBus.Current无法解析请求作用域在请求作用域之外调用MessageBus.Current—— 例如在static工具方法或线程池回调中调用会抛MessageBusException确无作用域的场景请显式从 DI 注入IMessageBus事件发布时机—— Memory 传输默认阻塞式发布若处理器执行缓慢且想改为异步请参考 docs/provider_memory.md 中的 Asynchronous Publish 一节处理器数量无上限—— 同一事件类型可以有任意多个IConsumerTSlimMessageBus 会自动广播给全部订阅者小结用 SlimMessageBus 实现 DDD 领域事件的精髓可以浓缩为一句话聚合根await MessageBus.Current.Publish(event)处理器实现IConsumerT其余交给AutoDeclareFromAssemblyContaining。借助MessageBus.Current静态访问器的作用域感知能力领域事件与 Web 请求共享同一个 DI Scope既解耦又保持了事务一致性——而这正是进程内消息总线最优雅的用法。【免费下载链接】SlimMessageBusLightweight message bus interface for .NET (pub/sub and request-response) with transport plugins for popular message brokers.项目地址: https://gitcode.com/gh_mirrors/sl/SlimMessageBus创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表