Last month I posted about how to use Rebus with Azure Storage Queues. This allowed you to use the Azure Storage Emulator for local development, and a real Azure Storage Queue account in production. Of course, another benefit of using a messaging abstraction like Rebus is that you can switch transports easily.
In this post I want to explain how we could switch to SQL Server as a transport. It might not seem an obvious choice, but the reason I wanted to try it was to enable local development without needing to run the Azure Storage Emulator. I already had a SQL Server available (and containerized using the technique I wrote about yesterday), and that meant if I could switch Rebus to using that, I could have all my dependencies containerized for local development. This reduces the setup overhead for new developers wanting to work on the project, and also allows for integration tests to be runnable on any server that can host Docker containers. I don't think I would use SQL Server as a transport in production though - it still makes sense to me to use a dedicated messaging service like Azure Service Bus for that.
The configuration steps are very similar to those for Azure Storage Queues, so I'll only mention the differences.
First, add a NuGet reference to
Next, in the
ConfigureServices method for the project that will be listening on the queue, we need to call
UseSqlServer with details of the database to use. I've asked it to auto-create the tables used for queue messages.
var transportOptions = new SqlServerTransportOptions(sqlConnectionString); // possibly the default is true, so this line might not be needed transportOptions.SetEnsureTablesAreCreated(true); services.AddRebus((configure, provider) => configure .Logging(l => l.MicrosoftExtensionsLogging( provider.GetRequiredService<ILoggerFactory>())) .Transport(t => t.UseSqlServer(transportOptions, queueName)));
As before, in the
Configure method we can start listening with
And in the project that sends the message, the configuration is almost identical, except we use
UseSqlServerAsOneWayClient and need to set up routing from the message types we're sending to the queue names they should be sent to.
var transportOptions = new SqlServerTransportOptions(sqlConnectionString); services.AddRebus((configure, provider) => configure .Logging(l => l.MicrosoftExtensionsLogging( provider.GetRequiredService<ILoggerFactory>())) .Transport(t => t.UseSqlServerAsOneWayClient(transportOptions)) .Routing(r => r.TypeBased().Map<VoteMessage>(queueName)) );
The convenience of being able to switch out transports means we can easily use containerized transports for development, testing or even production environments if we want. I showed how to do this with SQL Server since that was most convenient for me as I already had a SQL Server, but Rebus supports several transports and some others that are easily containerized are RabbitMQ, MySql and PostgeSQL.