我们有一个发布消息的应用程序-PublishApp。
消息(MessageA和MessageB)由两个不同的消费者应用程序(ConsumerA和ConsumerB)拾取。
所有应用程序都使用SQL Server作为传输和Windsor配置,但这两个Consumer在SQL Server中有不同的数据库。
我们如何配置PublishApp来为ConsumerA发布MessageA,为ConsumerB发布MessageB
我已经尝试过使用这里描述的DetermineMessageOwnership
,但实际上似乎并没有调用它(没有命中断点)。对于返回的字符串端点应该是什么,我有点困惑
我希望我可以在Windsor中设置一个具有特定名称的IBus组件,然后在设置MessageB发布类时按名称引用该组件。然而,目前还不清楚如何在温莎的魔盒之外建立一个IBus,为我做这一切。
如果我尝试调用Configure.With(new WindsorContainerAdapter(container))
两次,那么使用Windsor配置会导致Windsor错误,因为它被解释为注册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"
注意:我不想监听多个总线,只想向它们发布事件。其他应用程序正在监视队列,每个应用程序只侦听一个队列上的一个事件。
我们最终通过删除WindsorContainerAdaptor
解决了这个问题。由于我们不处理任何消息,只处理发布/发送,因此我们不需要容器适配器中的任何"handler"内容,并且我们可以将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的依赖关系来注册它,并且PublishB
可以用对BusB的依赖关系注册。这些消息进入不同的数据库,并由不同的订阅者接收,以便在这些不同的数据库中进行工作。
首先:没有办法(至少目前)在两个SQL Server数据库之间传送消息。为了在端点之间发送/发布消息,您需要在一个共享数据库中使用一个表。
您的设置暗示了一些东西在那里,因为您使用"ConnectionStringA"
和"ConnectionStringB"
作为传输。
我不清楚你是否真的想/需要做pub/sub消息——当你想让每条消息有多个收件人时,pub/sub是你通常会使用的,这通常是某种事件(即一条名称为过去时的消息,如:"发生了这样和那样的事")。
如果您想要一个特定的邮件收件人,则需要bus.Send
该邮件,也就是说,您的端点映射将被命中,以便获得该邮件的目的地。
如果你告诉我更多关于你想要实现的目标,我相信我可以帮助你:)