我在我的ASP.net web api项目中使用NServicebus(版本4.6.3)和SQLTransport。对于不同环境(Dev,QA等)的队列,我有不同的连接字符串。我的配置如下所示:
public class BusConfigurator
{
public static IStartableBus Bus { get; private set; }
public static void DisposeBus()
{
if (Bus == null)
return;
Bus.Shutdown();
Bus.Dispose();
Bus = null;
}
public static void InitializeServiceBus(string connectionString)
{
var configure = Configure.With()
.DefineEndpointName("MyEndPoint")
.Log4Net(new DebugAppender { Threshold = Level.Warn })
.UseTransport<SqlServer>(connectionString)
.PurgeOnStartup(false)
.SetDefaultTransactionLevel()
.UnicastBus(); // Error is thrown here on second call
configure.MyCustomSQLServerPersistence();
Bus = configure.CreateBus();
}
public static void StartBus()
{
Bus.Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
}
}
我在应用程序中有一个下拉列表,以便用户可以选择环境。根据选择,我想重新配置总线。所以,我调用DisposeBus然后将连接字符串传递给IntializeServiceBus方法,然后是startBus。它是第一次工作,但在使用不同的连接字符串再次调用时会抛出错误:
无法设置密钥的值:NServiceBus.Transport.ConnectionString。设置已被锁定以进行修改。请在配置管道中先前移动任何配置代码 来源= NServiceBus.Core 行= 0 BareMessage =无法设置key的值:NServiceBus.Transport.ConnectionString。设置已被锁定以进行修改。请在配置管道中移动任何配置代码
NServicebus是否打算以这种方式使用/配置? (我猜可能不是)如果没有,那么是否有解决方法/不同的方法呢?
答案 0 :(得分:2)
在V4或以下版本中,无法通过正常的人工方式进行操作。每个AppDomain只有一个总线。所有的配置API都是静态的,所以如果你尝试,你会得到你遇到的问题。
通过“人类手段”,我的意思是,在您的流程中启动新的AppDomain,在其中设置总线,然后在完成时将其拆除,可能会做一些疯狂的事情。这可能是可能的。我没试过。我不推荐它。
在V5中,配置API完全重新设计,不是静态的,所以这是可能的:
var cfg = new BusConfiguration();
// Set up all the settings with the new V5 Configuration API
using (var justOneBus = NServiceBus.Bus.Create(cfg).Start())
{
// Use justOneBus, then it gets disposed when done.
}
没错。这是一次性的。然后你可以再做一次。在您的情况下,您不希望将其放在using
块中 - 您可能希望在某处设置它,并且当下拉列表切换时,在当前实例上调用Dispose并使用新参数重建它。
但请记住,总线的创建成本仍然很高。它绝对是你想要作为应用程序范围的单例(或类似单例)实例处理的东西。你肯定不希望每个网页请求单独一个。