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

时间:2017-02-13 11:50:13

标签: generics handlers rebus

我的处理程序遇到了一些问题,而不是"捕捉"我的活动。 我目前的结构是,我在一个独立的包装中有一个包装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创建处理程序

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

1 个答案:

答案 0 :(得分:0)

如果我是你,我会丢弃信封的东西 - Rebus已经有了一个机制,允许在发送时将标题附加到邮件,所以如果你愿意,你可以添加自定义的东西。

当然,限制是您的额外数据需要表示为string - string键值对,但是再次: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>>