NserviceBus。如何在不同的AppDomains中启动多条总线?
我想在一个进程中有几条总线。我用谷歌搜索了一下,发现只有拥有多个应用程序域才有可能。但我无法让它发挥作用。
这是我的代码示例(我在一个类库中完成所有操作):
using System;
using System.Diagnostics;
using System.Reflection;
using MyMessages;
using NServiceBus;
using NServiceBus.Config;
using NServiceBus.Config.ConfigurationSource;
namespace Subscriber1
{
public class Sender
{
public static void Main()
{
var domain = AppDomain.CreateDomain("someDomain", AppDomain.CurrentDomain.Evidence);
domain.Load(Assembly.GetExecutingAssembly().GetName());
domain.CreateInstance(Assembly.GetExecutingAssembly().FullName, typeof (PluginBusCreator).FullName);
//here I have some code to send messages to "PluginQueue".
}
}
public class PluginBusCreator
{
public PluginBusCreator()
{
var Bus = Configure.With(
Assembly.Load("NServiceBus"), Assembly.Load("NServiceBus.Core"),
Assembly.LoadFrom("NServiceBus.Host.exe"), Assembly.GetCallingAssembly())
.CustomConfigurationSource(new PluginConfigurationSource())
.SpringFrameworkBuilder()
.XmlSerializer().MsmqTransport()
.UnicastBus().LoadMessageHandlers<First<SomeHandler>>().CreateBus().Start();
}
protected IBus Bus { get; set; }
}
class PluginConfigurationSource : IConfigurationSource
{
public T GetConfiguration<T>() where T : class
{
{
if (typeof (T) == typeof (MsmqTransportConfig))
return new MsmqTransportConfig
{
ErrorQueue = "error",
InputQueue = "PluginQueue",
MaxRetries = 1,
NumberOfWorkerThreads = 1
} as T;
return null;
}
}
}
public class SomeHandler : IHandleMessages<EventMessage1>
{
public void Handle(EventMessage1 message)
{
Debugger.Break();
}
}
}
而且我没有调用处理程序。 如果您有任何想法,请帮忙。我经常与这个问题作斗争。 另外,如果需要发布完整代码,请告知。
我需要几条总线来解决以下问题:
我有我的目标应用程序,以及它的几个插件。我们决定根据服务总线模式制作插件。
每个插件可以有多个配置文件。
因此,目标应用程序(它是网络应用程序)正在发布消息,其中某些内容发生了变化。订阅此消息的每个插件都需要对每个配置文件执行一些操作。但插件对其配置文件一无所知(客户正在编写插件)。当消息处理开始时,插件应该只注入配置文件。
我们决定有一些 RecepientList(模式在“企业集成模式”中描述),它了解插件配置文件,迭代它们并重新发送注入配置文件的消息。(因此,如果插件有多个配置文件,则多条消息将发送到它)。
但我不想在新进程中调用每个插件。完美地我想在启动期间为每个插件动态配置总线。一切都在一个过程中。但看来我需要在单独的应用程序域中执行此操作。所以我遇到了上面描述的问题:-)。
I want to have several buses in one process. I googled about this and found that it is possible only if having several AppDomains. But I cannot make it work.
Here is my code sample (I do everything in one class library):
using System;
using System.Diagnostics;
using System.Reflection;
using MyMessages;
using NServiceBus;
using NServiceBus.Config;
using NServiceBus.Config.ConfigurationSource;
namespace Subscriber1
{
public class Sender
{
public static void Main()
{
var domain = AppDomain.CreateDomain("someDomain", AppDomain.CurrentDomain.Evidence);
domain.Load(Assembly.GetExecutingAssembly().GetName());
domain.CreateInstance(Assembly.GetExecutingAssembly().FullName, typeof (PluginBusCreator).FullName);
//here I have some code to send messages to "PluginQueue".
}
}
public class PluginBusCreator
{
public PluginBusCreator()
{
var Bus = Configure.With(
Assembly.Load("NServiceBus"), Assembly.Load("NServiceBus.Core"),
Assembly.LoadFrom("NServiceBus.Host.exe"), Assembly.GetCallingAssembly())
.CustomConfigurationSource(new PluginConfigurationSource())
.SpringFrameworkBuilder()
.XmlSerializer().MsmqTransport()
.UnicastBus().LoadMessageHandlers<First<SomeHandler>>().CreateBus().Start();
}
protected IBus Bus { get; set; }
}
class PluginConfigurationSource : IConfigurationSource
{
public T GetConfiguration<T>() where T : class
{
{
if (typeof (T) == typeof (MsmqTransportConfig))
return new MsmqTransportConfig
{
ErrorQueue = "error",
InputQueue = "PluginQueue",
MaxRetries = 1,
NumberOfWorkerThreads = 1
} as T;
return null;
}
}
}
public class SomeHandler : IHandleMessages<EventMessage1>
{
public void Handle(EventMessage1 message)
{
Debugger.Break();
}
}
}
And I don't get handler invoked.
If you have any ideas, please help. I'm fighting this problem a lot of time.
Also if full code need to be published, please tell.
I need several buses to solve the following problem :
I have my target application, and several plugins with it. We decided to make our plugins according to service bus pattern.
Each plugin can have several profiles.
So, target application(it is web app.) is publishing message, that something has changed in it. Each plugin which is subscribed to this message, need to do some action for each profile. But plugin knows nothing about its profiles (customers are writing plugins). Plugin should only have profile injected in it, when message handling started.
We decided to have some RecepientList (pattern is described in "Enterprise Integration Patterns"), which knows about plugin profiles, iterates through them and re-send messages with profiles injected.(So if plugin has several profiles, several messages will be sent to it).
But I don't want to have each plugin invoked in a new process. Perfectly I want to dynamically configure buses for each plugin during start. All in one process. But it seems I need to do it in separate AppDomains. So I have a problem described above:-).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Sergey,
我不清楚为什么每个插件都需要有自己的总线。他们不能都坐同一辆公共汽车吗?每个插件开发人员都会像以前一样编写他们的消息处理程序,并且订阅将通过总线自动发生。
然后,您也不需要指定加载每个 NServiceBus DLL。
顺便说一句,按名称加载程序集往往会导致问题 - 尝试使用它来指定程序集:
typeof(IMessage).Assembly、 typeof(MsmqTransportConfig).Assembly、 typeof(IConfigureThisEndpoint).Assembly
Sergey,
I'm unclear as to why each plugin needs to have its own bus. Could they all not sit on the same bus? Each plugin developer would write their message handlers as before, and the subscriptions would happen automatically by the bus.
Then, also, you wouldn't need to specify to load each of the NServiceBus DLLs.
BTW, loading an assembly by name tends to cause problems - try using this to specify assemblies:
typeof(IMessage).Assembly, typeof(MsmqTransportConfig).Assembly, typeof(IConfigureThisEndpoint).Assembly