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

Generics Rebus:如何使用泛型处理事件类型,generics,handlers,rebus,Generics,Handlers,Rebus,我的处理程序无法“捕获”我的事件,这让我有些麻烦。 我目前的结构是,我在一个单独的包中有一个关于Rebus的包装器,该包装器包装Rebus的方法,并公开一个工厂,以便与I.e.Autofac一起使用-到目前为止还不错 然后,我将所有域事件放在单独的包和名称空间中,这样它们就不知道Rebus,反之亦然。他都是从类型IDistributedEvent派生的,并实现了抽象类型DistributedEvent 当我发布一个事件时,比如说MessageSent,我然后在我的包装器中制作一个信封事件BusE

我的处理程序无法“捕获”我的事件,这让我有些麻烦。 我目前的结构是,我在一个单独的包中有一个关于Rebus的包装器,该包装器包装Rebus的方法,并公开一个工厂,以便与I.e.Autofac一起使用-到目前为止还不错

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

当我发布一个事件时,比如说
MessageSent
,我然后在我的包装器中制作一个信封事件
BusEvent
,其中我将域事件设置为
有效负载
属性:

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() },
    } );
}
公共任务发布(T有效负载,TimeSpan过期),其中T:IDistributedEvent
{
var消息=新总线事件{有效负载=有效负载};
返回InternalBus.Publish(消息,新字典{
{Headers.TimeToBeReceived,expiration.ToString()},
{“pd version”,payload.EventVersion.ToString()},
} );
}
这样做的原因是能够随着时间的推移添加一些元数据(但这可能是错误的做法)

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


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

如果我是你,我会放弃信封内容–Rebus已经有了一种机制,允许在发送邮件时将邮件头附加到邮件上,因此如果你愿意,可以添加自定义内容

当然,限制是您的额外数据需要表示为
string
-
string
键值对,但是,再说一次:JSON是一个字符串,所以任何事情都是可能的;)

我看不出为什么它不应该与您自制的通用信封一起使用——如果您的处理程序注册为正确的
IHandleMessages
,当发送的消息是
YourMessage
时,它应该可以正常工作

是因为您希望多态分派与实现
IHandleMessages其中T:IDistributedEvent
的通用处理程序一起工作吗?因为接收类型为
BusEvent
的消息将导致在Autofac中查找以下处理程序,所以它将不起作用:

IHandleMessages<BusEvent<MessageSent>>
IHandleMessages<object>
IHandleMessages
IHandleMessages
因为这是Rebus在查找以
BusEvent
开头的继承链时发现的,但显然不包括

IHandleMessages<BusEvent<DistributedEvent>>
IHandleMessages

IHandleMessages

如果我是你,我会抛弃信封的东西——Rebus已经有了一种机制,允许在发送邮件时将邮件头附加到邮件上,因此如果你愿意,可以添加自定义的东西

当然,限制是您的额外数据需要表示为
string
-
string
键值对,但是,再说一次:JSON是一个字符串,所以任何事情都是可能的;)

我看不出为什么它不应该与您自制的通用信封一起使用——如果您的处理程序注册为正确的
IHandleMessages
,当发送的消息是
YourMessage
时,它应该可以正常工作

是因为您希望多态分派与实现
IHandleMessages其中T:IDistributedEvent
的通用处理程序一起工作吗?因为接收类型为
BusEvent
的消息将导致在Autofac中查找以下处理程序,所以它将不起作用:

IHandleMessages<BusEvent<MessageSent>>
IHandleMessages<object>
IHandleMessages
IHandleMessages
因为这是Rebus在查找以
BusEvent
开头的继承链时发现的,但显然不包括

IHandleMessages<BusEvent<DistributedEvent>>
IHandleMessages

IHandleMessages

我决定放弃
总线事件
,这显然让事情变得更简单。然而,我仍然无法让多态调度工作。我有一个处理程序,它在订阅了
IDistributedEvent
的总线实例上实现
IHandleMessages
处理程序类型是否在容器中注册,以便在解析IHandleMessages时返回?另一件事:您仍然需要订阅
SomeEvent
或任何具体类型–当Rebus发布消息时,它会根据消息类型推断主题,默认情况下,消息类型是(简单的)程序集限定类型名称,例如类似于
MyMessages.SomeEvent,MyMessages
yes:
.Register((ctx)=>new CatchAllHandler{name=name})我现在使用的是
内置HandlerActivator
,看起来订阅的工作方式与我预期的不同。我应该提到我在处理程序中使用的完整名称空间:
MyCompany.Events.Abstractions.DistributedEvent
(还有订阅。
MyCompany.Events.Distributed.Domain.Messaging.MessageSent:MyCompany.Events.Abstractions.DistributedEvent
是正在发布的类型。我决定放弃
BusEvent
,这显然让它更简单了。但是,我仍然无法让多态分派工作。我有一个实现
的处理程序>在订阅了
IDistributedEvent
的总线实例上,IHandleMessages
处理程序类型是否在容器中注册,以便在解析IHandleMessages时返回?另一件事:当Rebus发布消息时,您仍然需要订阅
SomeEvent
或任何具体类型从消息类型推断主题,默认情况下,消息类型是(简单)程序集限定类型名称,例如类似于
MyMessages.SomeEvent,