如何从已实现的IDomainEvent接口发布特定领域事件(MassTransit)
解决MassTransit发布具体领域事件的问题
首先纠正你代码里的一个错误:IDomainEvent应该定义为接口而非类,否则无法实现多态特性:
public interface IDomainEvent { }
要让MassTransit识别并发布事件的具体类型(而非接口类型),触发对应具体事件的消费者,有两种简单可行的方案:
方案一:使用非泛型Publish重载(推荐)
MassTransit的IBus提供了直接指定消息类型的非泛型Publish方法,你可以传入事件的实际类型和事件对象:
foreach (IDomainEvent personEvent in person.Events) { await _bus.Publish(personEvent.GetType(), personEvent, CancellationToken.None); }
这个方法会根据你传入的实际类型发布消息,精准触发对应具体事件的消费者。
方案二:通过反射调用泛型Publish方法
如果需要使用泛型版本的Publish,可以通过反射动态创建对应类型的泛型方法并执行:
foreach (IDomainEvent personEvent in person.Events) { var eventType = personEvent.GetType(); // 获取IBus的Publish<T>(object, CancellationToken)方法 var publishMethod = typeof(IBus).GetMethod(nameof(IBus.Publish), new[] { typeof(object), typeof(CancellationToken) }) ?.MakeGenericMethod(eventType); if (publishMethod != null) { await (Task)publishMethod.Invoke(_bus, new object[] { personEvent, CancellationToken.None }); } }
原写法失效的原因
你之前的_bus.Publish(personEvent)会被C#编译器静态解析为Publish<IDomainEvent>,MassTransit会将消息标记为IDomainEvent类型,只有订阅该接口的消费者会收到消息。而通过上述方法指定实际类型后,MassTransit会按具体事件类型路由,触发对应的PersonCreatedConsumer或PersonPositionCreatedConsumer。
内容的提问来源于stack exchange,提问作者Esteban Hugo Somma
相关产品推荐
相关产品推荐

