MASA Framework -- EventBus入门与设计

概述事件总线是一种事件发布/订阅结构 , 通过发布订阅模式可以解耦不同架构层级 , 同样它也可以来解决业务之间的耦合,它有以下优点

  • 松耦合
  • 横切关注点
  • 可测试性
  • 事件驱动
发布订阅模式通过下图我们可以快速了解发布订阅模式的本质
  1. 订阅者将自己关心的事件在调度中心进行注册
  2. 事件的发布者通过调度中心把事件发布出去
  3. 订阅者收到自己关心的事件变更并执行相对应业务
  4. 其中发布者无需知道订阅者是谁,订阅者彼此之间也互不认识 , 彼此之间互不干扰
事件总线类型在Masa Framework中 , 将事件划分为
  • 进程内事件 (Event)
本地事件,它的发布与订阅需要在同一个进程中,订阅方与发布方需要在同一个项目中
  • 跨进程事件 (IntegrationEvent)
集成事件,它的发布与订阅一定不在同一个进程中 , 订阅方与发布方可以在同一个项目中,也可以在不同的项目中
下面我们会用一个注册用户的例子来说明如何使用本地事件
入门
  • 安装.NET 6.0
  1. 新建ASP.NET Core 空项目Assignment.InProcessEventBus,并安装Masa.Contrib.Dispatcher.Events
dotnet new web -o Assignment.InProcessEventBuscd Assignment.InProcessEventBusdotnet add package Masa.Contrib.Dispatcher.Events --version 0.7.0-preview.7
  1. 注册EventBus (用于发布本地事件), 修改Program.cs
builder.Services.AddEventBus();
  1. 新增RegisterUserEvent类并继承Event,用于发布注册用户事件
public record RegisterEvent : Event{    public string Account { get; set; }    public string Email { get; set; }    public string Password { get; set; }}
  1. 新增注册用户处理程序
在指定事件处理程序方法上增加特性 EventHandler,并在方法中增加参数 RegisterUserEvent
public class UserHandler{    private readonly ILogger<UserHandler>? _logger;    public UserHandler(ILogger<UserHandler>? logger = null)    {        //todo: 根据需要可在构造函数中注入其它服务 (需支持从DI获取)        _logger = logger;    }    [EventHandler]    public void RegisterUser(RegisterUserEvent @event)    {        //todo: 1. 编写注册用户业务        _logger?.LogDebug("-----------{Message}-----------", "检测用户是否存在并注册用户");        //todo: 2. 编写发送注册通知等        _logger?.LogDebug("-----------{Account} 注册成功 {Message}-----------", @event.Account, "发送邮件提示注册成功");    }}
注册用户的处理程序可以放到任意一个类中,但其构造函数参数必须支持从DI获取,且处理程序的方法仅支持 Task或 Void 两种, 不支持其它类型
  1. 发送注册用户事件,修改Program.cs
app.MapPost("/register", async (RegisterUserEvent @event, IEventBus eventBus) =>{    await eventBus.PublishAsync(@event);});进阶处理流程EventBus的 请求管道包含一系列请求委托,依次调用 。它们与ASP.NET Core中间件有异曲同工之妙,区别点在于中间件的执行顺序与注册顺序相反,最先注册的最后执行
MASA Framework -- EventBus入门与设计

文章插图
每个委托均可在下一个委托前后执行操作 , 其中TransactionMiddleware是EventBus发布后第一个要进入的中间件 (默认提供),并且它是不支持多次嵌套的 。
EventBus 支持嵌套,这意味着我们可以在Handler中重新发布一个新的Event , 但TransactionMiddleware仅会在最外层进入时被触发一次

推荐阅读