发布到具有不同商店的多个Rebus队列

时间:2015-12-02 16:59:58

标签: c# castle-windsor rebus

我们有一个发布消息的应用程序 - PublishApp。

消息(MessageA和MessageB)由两个不同的消费者应用程序(ConsumerA和ConsumerB)选取。

所有应用程序都使用SQL Server作为传输和Windsor配置,但两个使用者在SQL Server中具有不同的数据库。

我们如何配置PublishApp为ConsumerB发布MessageA,为ConsumerB发布MessageB?

我已尝试使用here所述的DetermineMessageOwnership,但似乎并未实际调用(没有断点命中)。关于返回的字符串端点应该是什么,我有点神秘。

我希望我能在Windsor中设置一个具有特定名称的IBus组件,然后在设置我的MessageB-publishing类时按名称引用它。然而,目前还不清楚如何在魔术盒外面设置一个IBus,这对我来说就是一切。

如果我尝试两次调用Configure.With(new WindsorContainerAdapter(container)),那么摆弄温莎配置会导致温莎错误,因为它被解释为两次注册IBus接口。我无法在此处看到一个扩展点,为IBus个实例中的一个提供名称,从而在Windsor中区分它们。

或者,尝试重用Configure.With...调用会抛出一个错误,告诉我我已经在配置器上调用了.Transport()两次,这也是不允许的(但这会让我使用不同的连接字符串。 ..)

添加XML配置将允许我为不同的消息指定不同的端点,但不是不同的SQL连接字符串。

我最想要的是:

// Set up Bus A
var busA = Configure.With(new WindsorContainerAdapter(container))
    .Transport(tc => tc.UseSqlServerInOneWayClientMode("ConnectionStringA"))
    .Subscriptions(sc => sc.StoreInSqlServer("ConnectionStringA", "RebusSubscriptions"))
    .CreateBus()
    .Start();

// Set up Bus B
var busB = Configure.With(new WindsorContainerAdapter(container))
    .Transport(tc => tc.UseSqlServerInOneWayClientMode("ConnectionStringB"))
    .Subscriptions(sc => sc.StoreInSqlServer("ConnectionStringB", "RebusSubscriptions"))
    .CreateBus()
    .Start();

// Register Bus A in Windsor
container.Register(Component.For<IBus>()
    .Named("BusA")
    .Instance(busA));

// Register a class that depends on IBus, and set it to use Bus A
container.Register(Component.For<IPublishA>()
    .ImplementedBy<PublishA>()
    .DependsOn(Dependency.OnComponent(typeof(IBus), "BusA"));

// And a registration also for IBus B, and for IPublishB to reference named "BusB"

注意:我不想听多个总线,只向他们发布事件。其他应用程序正在监视队列,每个应用程序仅侦听一个队列中的一个事件。

2 个答案:

答案 0 :(得分:2)

我们最终通过放弃WindsorContainerAdaptor解决了这个问题。由于我们不处理任何邮件,只发布/发送,因此我们不需要任何“处理程序”。容器适配器中的东西,我们可以将IBus组件的注册切换到配置/启动之外,而不是在其中。这使我们可以控制IBus注册。

    public static void ConfigureAndStartBus(IWindsorContainer container)
    {
        _RegisterBus(container, "ConnectionStringA" "BusA");
        _RegisterBus(container, "ConnectionStringB" "BusB");
    }

    private static void _RegisterBus(IWindsorContainer container, string connectionString, string busName)
    {
        var bus = Configure.With(new BuiltinContainerAdapter())
            .Transport(tc => tc.UseSqlServerInOneWayClientMode(connectionString))
            .Subscriptions(sc => sc.StoreInSqlServer(connectionString, "RebusSubscriptions"))
            .CreateBus()
            .Start();

        container.Register(
            Component.For<IBus>()
                .Named(busName)
                .LifestyleSingleton()
                .Instance(bus));
    }

然后在类PublishA中,我们可以通过对BusA的依赖来注册它,并且可以使用对BusB的依赖注册PublishB。这些消息将转发到不同的数据库,并由不同的订阅者接收,以便在这些不同的数据库中工作。

答案 1 :(得分:0)

首先:在两个SQL Server数据库之间发送消息是没有办法(至少目前)。为了在端点之间发送/发布消息,您需要在一个共享数据库中使用一个表

由于您正在使用"ConnectionStringA""ConnectionStringB"进行传输,因此您的设置会提示某些内容。

我不清楚你是否真的想要/需要做pub / sub消息传递 - 当你想要每个消息的多个收件人时,你通常会使用pub / sub,这通常是某种event(即名称为过去时的消息,如:&#34; this and that happen&#34;)。

如果您希望某个邮件的特定收件人,您希望bus.Send该邮件,那就是您的端点映射将被点击以获取邮件的目的地。

如果您告诉我更多关于您正在努力实现的目标,我相信我可以帮助您:)