Rebus:如何使用泛型处理事件类型

Rebus: How to handle event types with generics

我的处理程序有一些问题,而不是 "catching" 我的事件。 我目前的结构是,我在一个单独的包中有一个 Rebus 的包装器,它包装 Rebus 的方法并公开一个工厂以与 Autofac 一起使用 - 到目前为止一切顺利。

然后我将所有领域事件放在单独的包和命名空间中,这样他们就不知道 Rebus,反之亦然。他都派生自类型IDistributedEvent并实现了抽象类型DistributedEvent

当我发布一个事件时,说 MessageSent,然后我在我的包装器中创建一个信封事件 BusEvent,我将域事件设置为 Payload 属性 :

public Task Publish<T>( T payload, TimeSpan expiration ) where T : IDistributedEvent
{
    var message = new BusEvent<T> { Payload = payload };
    return InternalBus.Publish( message, new Dictionary<string, string> {
        { Headers.TimeToBeReceived, expiration.ToString() },
        { "pd-version", payload.EventVersion.ToString() },
    } );
}

这样做的原因是能够随着时间的推移添加一些元数据(但也许这是错误的做法)。

无论如何,我的问题是现在我的处理程序没有被识别为可以处理类型 BusEvent<MessageSent> 的处理程序,即使我使用接口 IHandleMessages<BusEvent<T>> where T : IDistributedEvent

创建处理程序

所以问题是:我在这里做错了吗,或者这只是一种糟糕的做法。因此,我应该只删除包络类型并直接处理域事件类型吗?

如果我是你,我会放弃信封的东西 – Rebus 已经有一个机制允许在你发送消息时附加 headers 到消息,所以你可以根据需要添加自定义的东西.

当然,限制是您的额外数据需要表示为 string-string key-value 对,但话又说回来:JSON 是一个字符串,所以一切皆有可能 ;)

我看不出有任何理由为什么它不能与您自制的通用信封一起使用 – 如果您的处理程序注册为正确的 IHandleMessages<BusEvent<YourMessage>> 而发送的消息是 YourMessage,它应该可以正常工作。

是否因为您希望多态分派与实现 IHandleMessages<BusEvent<T>> where T : IDistributedEvent 的通用处理程序一起工作?因为那样它就不起作用了,因为接收到 BusEvent<MessageSent> 类型的消息会导致在 Autofac 中查找以下处理程序:

IHandleMessages<BusEvent<MessageSent>>
IHandleMessages<object>

因为这是 Rebus 在查找以 BusEvent<> 开头的继承链时找到的内容,但显然不包括

IHandleMessages<BusEvent<DistributedEvent>>

IHandleMessages<BusEvent<IDistributedEvent>>