Multi-Instance Mode

Component: Transport Bridge
NuGet Package: NServiceBus.Transport.Bridge (1-pre)

This is a Preview project
This page targets a pre-release version. Pre-releases are subject to change and samples are not guaranteed to be fully functional.

This is sample shows how to use the NServiceBus.Transport.Bridge instead of the deprecated SQL Server transport multi-instance mode.

Prerequisites

An instance of SQL Server Express, accessible as .\SqlExpress.

At startup, each endpoint creates its required SQL assets, including databases, tables, and schemas.

The databases created by this sample are NsbSamplesSqlMultiInstanceReceiver and NsbSamplesSqlMultiInstanceSender.

Running the project

  1. Start the following projects:

    1. Sender
    2. Receiver
    3. Bridge
  2. Press enter in the Sender's console window to send a new message.

Verifying that the sample works correctly

  1. The Receiver displays information that an order was submitted.
  2. The Sender displays information that a response arrived for the same order.

Code walk-through

The sample contains the following projects:

  • Sender: A console application responsible for sending the initial ClientOrder message and processing the follow-up ClientOrderResponse message.
  • Receiver: A console application responsible for processing the order message.
  • Bridge: A console application responsible for routing messages across the two database instances.
  • Messages: A class library containing message definitions.
  • Helpers: A class library for creating the databases and schemas.

Sender project

The Sender does not store any data. It mimics a front-end system where orders are submitted by the users and passed via the bus to the back-end. It is configured to use the SQL Server transport. Other than that, it is unaware the other endpoint is running on a different database instance.

var endpointConfiguration = new EndpointConfiguration("Samples.SqlServer.MultiInstanceSender");
var transport = endpointConfiguration.UseTransport<SqlServerTransport>();
transport.ConnectionString(connectionString);
endpointConfiguration.EnableInstallers();

transport.Routing().RouteToEndpoint(typeof(ClientOrder), "Samples.SqlServer.MultiInstanceReceiver");

The Sender sends a message to the Receiver:

var order = new ClientOrder
{
    OrderId = Guid.NewGuid()
};
await endpoint.Send(order)
    .ConfigureAwait(false);

Receiver project

The Receiver mimics a back-end system. It is configured to use the SQL Server transport but has a different connectionstring from the Sender.

var endpointConfiguration = new EndpointConfiguration("Samples.SqlServer.MultiInstanceReceiver");
var transport = endpointConfiguration.UseTransport<SqlServerTransport>();
transport.ConnectionString(ConnectionString);
endpointConfiguration.EnableInstallers();

Note that the endpoint configuration contains no routing information, as the response message is a regular reply and NServiceBus, together with the Bridge, will take care of all the routing with reply messages. The Receiver replies with ClientOrderResponse back to the Sender.

public Task Handle(ClientOrder message, IMessageHandlerContext context)
{
    log.Info($"Handling ClientOrder with ID {message.OrderId}");
    var clientOrderAccepted = new ClientOrderResponse
    {
        OrderId = message.OrderId
    };
    return context.Reply(clientOrderAccepted);
}

Bridge

The Bridge is configured with two transports. As both transports are of the same SqlServerTransport type, it is required to provide a name to each BridgeTransport to distinguish between the two in logfiles.

var receiverTransport = new BridgeTransport(new SqlServerTransport(ReceiverConnectionString))
{
    Name = "Receiver",
    AutoCreateQueues = true
};

receiverTransport.HasEndpoint("Samples.SqlServer.MultiInstanceReceiver");

var senderTransport = new BridgeTransport(new SqlServerTransport(SenderConnectionString))
{
    Name = "Sender",
    AutoCreateQueues = true
};

senderTransport.HasEndpoint("Samples.SqlServer.MultiInstanceSender");

bridgeConfiguration.AddTransport(receiverTransport);
bridgeConfiguration.AddTransport(senderTransport);

Both transports have the endpoints defined on their side and as a result, the Bridge will mimic those endpoints on the other side. This way it becomes transparent to actual endpoints on either side that those endpoints are actually bridged.

Related Articles


Last modified