diff --git a/docs/features/message-pumps/service-bus.md b/docs/features/message-pumps/service-bus.md index a299b44b..bbc8105a 100644 --- a/docs/features/message-pumps/service-bus.md +++ b/docs/features/message-pumps/service-bus.md @@ -15,19 +15,38 @@ Azure Service Bus Message Pump will perform all the plumbing that is required fo As a user, the only thing you have to do is **focus on processing messages, not how to get them**. -You can do this by creating a message handler which derives from `AzureServiceBusMessagePump` +You can do this by creating a message handler which implements from `IAzureServiceBusMessageHandler` (or `IMessageHandler`). Here is an example of a message handler that expects messages of type `Order`: ```csharp -public class OrdersMessageHandler : AzureServiceBusMessagePump +public class OrdersMessageHandler : IAzureServiceBusMessageHandler { - public OrdersMessageHandler(IConfiguration configuration, IServiceProvider serviceProvider, ILogger logger) - : base(configuration, serviceProvider, logger) + public async Task ProcessMessageAsync( + Order orderMessage, + AzureServiceBusMessageContext messageContext, + MessageCorrelationInfo correlationInfo, + CancellationToken cancellationToken) { + Logger.LogInformation("Processing order {OrderId} for {OrderAmount} units of {OrderArticle} bought by {CustomerFirstName} {CustomerLastName}", orderMessage.Id, orderMessage.Amount, orderMessage.ArticleNumber, orderMessage.Customer.FirstName, orderMessage.Customer.LastName); + + // Custom logic + + Logger.LogInformation("Order {OrderId} processed", orderMessage.Id); } +} +``` - protected override async Task ProcessMessageAsync(Order orderMessage, AzureServiceBusMessageContext messageContext, MessageCorrelationInfo correlationInfo, CancellationToken cancellationToken) +or with using the more general `IMessageHandler<>`, that will use the more general `MessageContext` instead of the one specific for Azure Service Bus. + +```csharp +public class OrdersMessageHandler : IMessageHandler +{ + public async Task ProcessMessageAsync( + Order orderMessage, + MessageContext messageContext, + MessageCorrelationInfo correlationInfo, + CancellationToken cancellationToken) { Logger.LogInformation("Processing order {OrderId} for {OrderAmount} units of {OrderArticle} bought by {CustomerFirstName} {CustomerLastName}", orderMessage.Id, orderMessage.Amount, orderMessage.ArticleNumber, orderMessage.Customer.FirstName, orderMessage.Customer.LastName); @@ -38,14 +57,6 @@ public class OrdersMessageHandler : AzureServiceBusMessagePump } ``` -As of today, the message handler is tightly coupled to the broker but overtime they will be decoupled. - -Over time you'll be able to: -- Bring your own deserialization -- Re-use a message handler across different brokers -- Use multiple message handlers and let the pump route the messages to the correct handler. -This can be based on message type, message context or custom message flow determination - ## Configuration Once the message handler is created, you can very easily configure it: @@ -55,11 +66,15 @@ public void ConfigureServices(IServiceCollection services) { // Add Service Bus Queue message pump and use OrdersMessageHandler to process the messages // ISecretProvider will be used to lookup the connection string scoped to the queue for secret ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING - services.AddServiceBusQueueMessagePump("ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING"); + services.AddServiceBusQueueMessagePump("ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING") + .WithServiceBusMessageHandler(); // Add Service Bus Topic message pump and use OrdersMessageHandler to process the messages on the 'My-Subscription-Name' subscription // ISecretProvider will be used to lookup the connection string scoped to the queue for secret ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING - services.AddServiceBusTopicMessagePump("My-Subscription-Name", "ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING"); + services.AddServiceBusTopicMessagePump("My-Subscription-Name", "ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING") + .WithServiceBusMessageHandler(); + + // Note, that only a single call to the `.WithServiceBusMessageHandler` has to be made when the handler should be used across message pumps. } ``` @@ -80,7 +95,7 @@ Next to that, we provide a **variety of overloads** to allow you to: public void ConfigureServices(IServiceCollection services) { // Specify the name of the Service Bus Queue: - services.AddServiceBusQueueMessagePump( + services.AddServiceBusQueueMessagePump( "My-Service-Bus-Queue-Name", "ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING"); @@ -91,12 +106,12 @@ public void ConfigureServices(IServiceCollection services) "ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING"); // Specify a topic subscription prefix instead of a name to separate topic message pumps. - services.AddServiceBusTopicPumpWithPrefix( + services.AddServiceBusTopicPumpWithPrefix( "My-Service-Bus-Topic-Name" "My-Service-Bus-Subscription-Prefix", "ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING"); - services.AddServiceBusTopicMessagePump( + services.AddServiceBusTopicMessagePump( "ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING", options => { @@ -117,7 +132,7 @@ public void ConfigureServices(IServiceCollection services) options.TopicSubscription = TopicSubscription.CreateOnStart | TopicSubscription.DeleteOnStop; }); - services.AddServiceBusQueueMessagePump( + services.AddServiceBusQueueMessagePump( "ARCUS_SERVICEBUS_ORDERS_CONNECTIONSTRING", options => { @@ -133,6 +148,11 @@ public void ConfigureServices(IServiceCollection services) // this job instance in a multi-instance deployment (default: guid). options.JobId = Guid.NewGuid().ToString(); }); + + // Multiple message handlers can be added to the servies, based on the message type (ex. 'Order', 'Customer'...), + // the correct message handler will be selected. + services.WithServiceBusMessageHandler() + .WithMessageHandler(); } ```