Skip to content

集成事件

由于领域事件仅在本地事务中使用,所以我们需要一种机制来在分布式系统中传递事件,使得事件的处理不阻断发起事件的命令的执行,这就是集成事件的作用。

注册集成事件服务

目前框架实现了CAP组件来支持集成事件,我们需要在Startup类中注册CAP组件:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCap(x =>
    {
        x.UseEntityFramework<AppDbContext>();
        x.UseRabbitMQ("localhost");
    });
}

// 配置CAP为集成事件实现
builder.Services.AddIntegrationEvents(typeof(Program))
        .UseCap(b =>
        {
            b.RegisterServicesFromAssemblies(typeof(Program));
            b.AddContextIntegrationFilters();
            b.UseMySql();
        });

发出集成事件

集成事件是由领域事件转换而来的,命名一般以IntegrationEvent结尾从而与领域事件区分,如OrderCreatedIntegrationEvent

要发出集成事件,我们需要定义一个IIntegrationEventConverter,框架会自动将领域事件转换为集成事件并发出。

public class OrderCreatedIntegrationEventConverter : 
    IIntegrationEventConverter<OrderCreatedDomainEvent, OrderCreatedIntegrationEvent>
{
    public OrderCreatedIntegrationEvent Convert(OrderCreatedDomainEvent domainEvent)
    {
        return new OrderCreatedIntegrationEvent(domainEvent.Order.Id);
    }
}

集成事件处理

集成事件处理器是一个实现了IIntegrationEventHandler<TIntegrationEvent>接口的类,其中TIntegrationEvent是集成事件的类型。

一般我们可以在集成事件处理器中做下列事情:

  • 发出命令
  • 调用外部服务

下面是一个集成事件处理器的例子:

public class OrderCreatedIntegrationEventHandler(IMediator mediator) : IIntegrationEventHandler<OrderCreatedIntegrationEvent>
{
    public async Task Handle(OrderCreatedIntegrationEvent eventData, CancellationToken cancellationToken)
    {
        //处理集成事件
        var cmd = new OrderPaidCommand(eventData.OrderId);
        await mediator.Send(cmd, cancellationToken);
    }
}

失败重试

我们借助CAP组件实现了集成事件,CAP组件提供了失败重试机制,当集成事件处理失败时,CAP会自动重试处理,默认情况下会重试10次。

限制条件

集成事件必须使用简单对象,因为集成事件会在需要支持Json格式序列化和反序列化并在分布式系统中传递。