我正在尝试在NServiceBus上构建一个层,以便其他开发人员使用它。
我正在尝试不使用配置文件并设法让发布者工作:
public class NServiceBusPublisher
{
private IBus _Bus { get; set; }
public void NServiceBusPublisher(string argInputQueue, string argErrorQueue)
{
Configure configure = NServiceBus.Configure.With().DefaultBuilder();
var transport = configure.Configurer.ConfigureComponent<MsmqTransport>(ComponentCallModelEnum.Singleton);
transport.ConfigureProperty(t => t.InputQueue, argInputQueue);
transport.ConfigureProperty(t => t.ErrorQueue, argErrorQueue);
transport.ConfigureProperty(t => t.NumberOfWorkerThreads, 1);
transport.ConfigureProperty(t => t.MaxRetries, 5);
_Bus =
configure
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.ImpersonateSender(false)
.CreateBus()
.Start();
}
public void Publish(NServiceBus.IMessage argMessage)
{
_Bus.Publish(argMessage);
}
}
我还希望拥有一个NServiceBus订阅服务器,并且只要消息继承自NServiceBus.IMessage,开发人员就可以订阅任意数量的消息类型:
public class NServiceBusSubscriber
{
private IBus _Bus { get; set; }
public void NServiceBusSubscriber(string argInputQueue, string argOutputQueue, string argErrorQueue, string messagesAssembly)
{
Configure configure = NServiceBus.Configure.With().DefaultBuilder();
var transport = configure.Configurer.ConfigureComponent<MsmqTransport>(ComponentCallModelEnum.Singleton);
transport.ConfigureProperty(t => t.InputQueue, argInputQueue);
transport.ConfigureProperty(t => t.ErrorQueue, argErrorQueue);
transport.ConfigureProperty(t => t.NumberOfWorkerThreads, 1);
transport.ConfigureProperty(t => t.MaxRetries, 5);
var ucb = configure.Configurer.ConfigureComponent<NServiceBus.Unicast.UnicastBus>(ComponentCallModelEnum.Singleton);
ucb.ConfigureProperty(u => u.MessageOwners, new Dictionary<string,string>()
{
{messagesAssembly, argOutputQueue}
});
_Bus =
configure
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.ImpersonateSender(false)
.DoNotAutoSubscribe()
.CreateBus()
.Start();
}
public void Subscribe<T>() where T : NServiceBus.IMessage
{
_Bus.Subscribe<T>();
}
}
问题是我找不到任何方法将事件处理程序附加到特定的消息类型。
你能帮我解决这个问题吗?
非常感谢。
答案 0 :(得分:1)
问题被问到已经有一段时间了,所以我不确定问题是否已经解决,但是这是使用Bus.Subscribe进行的一种方式(尽管其他受访者已经说过这不是这样做的规定方式NServiceBus)
使用subscribe overload
订阅消息类型 void Subscribe(Type messageType, Predicate<IMessage> condition);
然后您可以处理委托中的消息
private bool Handle(NServiceBus.IMessage nsbMsg)
{
//you get the message instance that you can handle
//return true
}
因此,您的代码将是
class MySubscriber
{
public IBus Bus {get; set;}
public void Subscribe()
{
Bus.Subscribe(typeof(MyMessage), Handle);
}
public void Handle(NServiceBus.IMessage nsbMsg)
{
var msg = nsbMsg as MyMessage;
//your code
return true;
}
}
但请注意,通过这样做,您必须自己管理处理程序的生命周期,否则NServiceBus将使用您选择的IOC框架为您管理。
如果您只是实现了IHandleMessage接口,那么您还必须明确地传递对IBus的引用,这将自动注入。
这里的架构点是NSB是一个完整的'ESB',它不仅仅是一个消息传递层。在你的ESB上添加另一层是恕我直言,抽象太多了。
答案 1 :(得分:1)
我认为您缺少NServiceBus背后的概念。
基于您显示的代码,我给人的印象是,您设想了发布消息的服务以及处理这些消息的其他服务。以我的经验,大多数进程都做这两种事情:它们订阅事件或处理传入的命令,结果发布新事件并发送新命令。 在您的设置中,您需要为每种消息类型具有发布者和订阅者实例。
NServiceBus是针对我所描述的情况而构建的。您配置并启动1个总线实例,这将协调整个应用程序。
如果要使开发人员更轻松地使用NServiceBus,我将只专注于配置部分。在我们公司中,我创建了一个ServicebusConfigurator类,该类根据我们公司的标准配置NServiceBus,并将其提取到.NET Core通用主机的框架和简单扩展方法中。开发人员只需编写以下代码即可创建一个承载NServiceBus终结点的Windows服务:
Text("something",style:isBold?_boldTextStyle:_normalTextStyle);
答案 2 :(得分:0)
由于您没有自动订阅,您需要做的第一件事是通过Bus.Subscribe()订阅消息类型。其他人可以在IWantToRunAtStartUp扩展点执行此操作(在某个类中实现接口)。从那里,每个订户将实现IHandleMessages&lt; T&gt;。接口。实现此接口会将您连接到消息,其中“T”是消息类型。
当NSB启动时,它将扫描本地bin目录并找到所有接口实现并在内部代表您连接它们。当那个类型的消息到达时,它会从那里调度到正确的处理程序。
答案 3 :(得分:0)
NServiceBus自动处理邮件订阅。当你调用Configure.With().... Start(); NServiceBus将扫描以确定哪些程序集实现了IHandleMessages(SomeMessage),它将向发布者发送订阅请求。
当您添加“DoNotAutoSubscribe”时,您必须手动获取正在处理的所有邮件,并为每个邮件执行Bus.Subscribe()。
除此之外,NServiceBus将自动处理传入消息到适当处理程序的路由。在上面的用户代码中,您是否收到错误消息或消息是否从队列中消失?