如何配置NServiceBus以扫描IMessage的程序集?

时间:2015-03-16 14:59:14

标签: c# nservicebus messaging

我正在处理我尚未编写的代码,并且正在尝试理解为什么某个特定功能不能按照我的意图运行。特别是,我的解决方案中有三个项目:

API
Messages
    Events
Processors

Events是Messages中的一个文件夹。 API将通过Messages/Events中定义的消息使用NServiceBus与处理器通信。 Messages/Events中的每个类都扩展了IMessage

现在在处理器和API共享的总线的配置文件中,我找到了这些行:

var conventionsBuilder = config.Conventions();
conventionsBuilder.DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("DE.STEP.Messages") && t.Namespace.EndsWith("Events"));
return config;

这是之前实现的,Messages/Events中的类没有在较早时间扩展IMessage,而是上面的代码定义了消息可以限定的位置和内容。现在,因为我已经介绍了IMessage,我想我可以删除这3行代码。但是,当我这样做时,没有消息从API进入我的队列。尝试此发布的代码为Bus.Publish<>();

我应该如何配置它,以便我不需要一个硬编码的字符串引用消息所在的程序集?我希望我的代码能够扫描解决方案以查找扩展IMessage的任何内容,并将其视为可以发布并可以处理的内容。

编辑:根据NServiceBus文档

By default, NServiceBus scans all assemblies in the endpoint 
bin folder to find types implementing its interfaces so that 
it can configure them automatically.

Messages.dll出现在API和处理器的bin中。因为Messages.dll包含我的所有IMessages,所以默认行为不足以使它们可用于发布/订阅吗?即不应该删除有问题的3行没有效果吗?

2 个答案:

答案 0 :(得分:0)

如果您不使用不引人注目的配置,事件的层次结构应如下所示:

ConcreteEvent : IEvent : IMessage

原因是,在查看了源代码之后,您的消息端点映射按如下方式处理:

foreach (var mapping in messageEndpointMappings)
{
    mapping.Configure((messageType, address) =>
    {
        var conventions = context.Settings.Get<Conventions>();
        if (!(conventions.IsMessageType(messageType) || conventions.IsEventType(messageType) || conventions.IsCommandType(messageType)))
        {
            return;
        }

        if (conventions.IsEventType(messageType))
        {
            router.RegisterEventRoute(messageType, address);
            return;
        }

        router.RegisterMessageRoute(messageType, address);
    });
}

Conventions.IsEventType是一个如下实现的查找:

EventsConventionCache.ApplyConvention(t, type => IsEventTypeAction(type));

我不会给你完整的调用堆栈,但基本上,你最终会在这里:

t => typeof(IEvent).IsAssignableFrom(t) && typeof(IEvent) != t

对于仅实施false的具体事件,这将评估为IMessage,因此永远不会为您的活动调用RegisterEventRoute,而是将其视为{{1} },遵循不同的路由规则(每IMessage只有一个路由)。

答案 1 :(得分:0)

简而言之,如果您没有使用不显眼的配置,则必须在事件类上安装IEvent接口才能使用IBus.Publish。