如何在Asp.net Web API中重新配置基于SQLTransport的NServicebus?

时间:2014-09-30 15:44:16

标签: c# asp.net asp.net-web-api nservicebus

我在我的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是否打算以这种方式使用/配置? (我猜可能不是)如果没有,那么是否有解决方法/不同的方法呢?

1 个答案:

答案 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并使用新参数重建它。

但请记住,总线的创建成本仍然很高。它绝对是你想要作为应用程序范围的单例(或类似单例)实例处理的东西。你肯定不希望每个网页请求单独一个。