定义 Integration Event
public class DemoIntegrationEvent : IntegrationEvent { public override string Topic { get; set; } = nameof(DemoIntegrationEvent);//dapr topic name //todo other properties }定义 DbContext(非必须,定义 DbContext 可以将本地消息表与业务事务联动)
public class CustomDbContext : IntegrationEventLogContext { public DbSet<User> Users { get; set; } = null!; public CustomDbContext(MasaDbContextOptions<CustomDbContext> options) : base(options) { } }发送 Event
IIntegrationEventBus eventBus; // from DI await eventBus.PublishAsync(new DemoIntegrationEvent());订阅 Event(基于 Dapr Pub/Sub 的版本)
[Topic("pubsub", nameof(DomeIntegrationEvent))] public async Task DomeIntegrationEventHandleAsync(DomeIntegrationEvent @event) { //todo } Domain Event Bus在领域中同时提供 Event Bus 和 Integration Event Bus 的能力,允许实时发送事件或在 Save 时一次性触发
Domain Event Bus 是最完整的能力,所以使用 Domain Event Bus 相当于已经开启了 Event Bus 和 Integration Event Bus,在 Domain Event Bus 内部会自动协调事件分类往 Event Bus 和 Integration Event Bus 分流
启用 Domain Event Bus
builder.Services .AddDomainEventBus(options => { options.UseEventBus()//Use in-process events .UseUoW<CustomDbContext>(dbOptions => dbOptions.UseSqlServer("server=localhost;uid=sa;pwd=P@ssw0rd;database=idientity")) .UseDaprEventBus<IntegrationEventLogService>()///Use cross-process events .UseEventLog<LocalMessageDbContext>() .UseRepository<CustomDbContext>(); })添加 DomainCommand
Domain Event 是进程内事件,IntegrationDomainEvent 是跨进程事件
public class RegisterUserSucceededIntegrationEvent : IntegrationDomainEvent { public override string Topic { get; set; } = nameof(RegisterUserSucceededIntegrationEvent); public string Account { get; set; } = default!; } public class RegisterUserSucceededEvent : DomainEvent { public string Account { get; set; } = default!; }进程内事件订阅
[EventHandler] public Task RegisterUserHandlerAsync(RegisterUserDomainCommand command) { //TODO }跨进程事件订阅
[Topic("pubsub", nameof(RegisterUserSucceededIntegrationEvent))] public async Task RegisterUserSucceededHandlerAsync(RegisterUserSucceededIntegrationEvent @event) { //todo }发送 DomainCommand
IDomainEventBus eventBus;//from DI await eventBus.PublishAsync(new RegisterUserDomainCommand()); 使用场景兼顾遗留系统对接
游走在云与非云中
流计算
微服务解耦和跨集群通信(需要将 Dapr Pub/Sub 改为 Dapr Binding,不难)
部分 AOP 类场景
总结事件驱动可以解决一些特定场景的问题,凡事都有两面性,在本来就很简单的业务场景中使用如此复杂的模式会带来不小的负担。
学以致用,学无止境。
开源地址MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks
MASA.Contrib:https://github.com/masastack/MASA.Contrib
MASA.Utils:https://github.com/masastack/MASA.Utils
MASA.EShop:https://github.com/masalabs/MASA.EShop
如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们