Reputation: 75
I'm trying to update this function to make use of Azure.Messaging.ServiceBus
and drop Microsoft.Azure.ServiceBus
altogether, however, I can't seem to find any resources for this. Anybody knows how to send a message to a topic using this package?
The older function is:
public async Task SendMessageToServiceBusTopic<T>(T request, string topicSubName, string submissionNumber)
{
ServiceBusConnectionStringBuilder serviceBusConnectionStringBuilder =
new ServiceBusConnectionStringBuilder(settings.ServiceBusConnectionString)
{
EntityPath = settings.ServiceBusTopic
};
TopicClient topicClient = new TopicClient(serviceBusConnectionStringBuilder);
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(request));
await topicClient.SendAsync(new Message(bytes)
{
CorrelationId = context.CorrelationId,
Label=topicSubName,
UserProperties = { new KeyValuePair<string, object>("TrackingId", submissionNumber) }
});
}
So far I have managed:
Am i headed in the right direction?
public async Task SendMessageToServiceBusTopic<T>(T request, string topicSubName, string submissionNumber)
{
ServiceBusClient client = new ServiceBusClient(settings.ServiceBusConnectionString);
ServiceBusSender s = client.CreateSender(settings.ServiceBusTopic);
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(request));
await s.SendMessageAsync(new ServiceBusMessage(bytes));
}
Upvotes: 5
Views: 5394
Reputation: 564
I was in the same situation like you (trying to migrate to Azure.Messaging.ServiceBus which is now the recommended NuGet from Microsoft).
You can have a look at the migration guide from their Github to have an idea of how to make the transition smoother: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/servicebus/Azure.Messaging.ServiceBus/MigrationGuide.md
/!\ IQueueClient and ITopicClient (both coming from Microsoft.Azure.ServiceBus) have been merged into a single object called ServiceBusSender.
Why ? to make our life easier ! Indeed, under the hood, ServiceBusSender now takes care of the process of sending the message, especially since a queue and a topic cannot have the same name if I'm not wrong.
Here's a sample code of mine to send a message using the new library:
/// <summary>
/// Send a message by serializing as JSON the object in input.
/// </summary>
/// <param name="queueOrTopicName">Name of the queue or topic where the message will be sent.</param>
/// <param name="messageToSend">Any C# object</param>
/// <returns></returns>
public async Task SendMessage(string queueOrTopicName, object messageToSend)
{
//ServiceBusSender should not be disposed (according to the documentation, Github, etc.)
await using ServiceBusClient client = new ServiceBusClient(connectionString: "Your-ServiceBus-ConnectionString");
await using ServiceBusSender sender = client.CreateSender(_queueOrTopicName);
// create a message that we can send. UTF-8 encoding is used when providing a string.
ServiceBusMessage message = BuildServiceBusMessage(messageToSend);
// Finally send the message
await sender.SendMessageAsync(message);
}
private ServiceBusMessage BuildServiceBusMessage<T>(T entity)
{
string serializedMessage = JsonConvert.SerializeObject(entity); // Still using Newtonsoft.Json but I don't see any obstacles of using System.Text.Json.
ServiceBusMessage message = new ServiceBusMessage(serializedMessage)
{
MessageId = Guid.NewGuid().ToString(),
ContentType = "application/json; charset=utf-8",
};
return message;
}
If you have any needs to do Dependency Injection (to re-use the same ServiceBusClient object and avoiding instanciating ServiceBusClient for each message you want to send for example), you can refer to this stackoverflow that I discovered this week
How to register ServiceBusClient for dependency injection?
Upvotes: 2
Reputation: 25994
While you can construct a Service Bus Client each time, it's not ideal. Assuming you're using the latest In-Proc SDK, you can use one of these options:
[FunctionName("PublishToTopic")]
public static async Task Run(
[TimerTrigger("0 */5 * * * *")] TimerInfo myTimer,
[ServiceBus("<topic_name>", Connection = "<connection_name>")] IAsyncCollector<ServiceBusMessage> collector)
{
await collector.AddAsync(new ServiceBusMessage(new BinaryData($"Message 1 added at: {DateTime.Now}")));
await collector.AddAsync(new ServiceBusMessage(new BinaryData($"Message 2 added at: {DateTime.Now}")));
}
Alternatively,
[FunctionName("PublishWithSender"]
public static async Task Run(
[TimerTrigger("0 */5 * * * *")] TimerInfo myTimer,
[ServiceBus("<topic_name>", Connection = "<connection_name>")] ServiceBusSender sender)
{
await sender.SendMessagesAsync(new[]
{
new ServiceBusMessage(new BinaryData($"Message 1 added at: {DateTime.Now}")),
new ServiceBusMessage(new BinaryData($"Message 2 added at: {DateTime.Now}"))
});
}
For Isolated Worker SDK it's somewhat different. See this post for details.
Upvotes: 1
Reputation: 18387
you're in the right direction. There's no easy migration tool/sample as they are different libraries dealing with the same service (Azure Service Bus).
Upvotes: 0