A new Azure Service Bus transport—but not just yet
If you’ve been looking forward to using .NET Core with NServiceBus on Azure, I’m afraid we’ve got some bad news. Instead of making their existing Azure Service Bus client library support .NET Core, Microsoft has released a brand-new incompatible client. This makes it impossible for us to upgrade the NServiceBus Azure Service Bus transport you know and love to support .NET Core as is, and forces us to write a brand-new transport as well.
Here’s the full story.
A tale of two clients
NServiceBus uses a Microsoft client library to talk to Azure Service Bus, and there are now two different clients. The older WindowsAzure.ServiceBus client only supports the full .NET Framework, so there’s no way our Azure Service Bus transport can support .NET Core using that.
But Microsoft has released a new Azure Service Bus client in the Microsoft.Azure.ServiceBus package, which targets .NET Standard 1.3 and the Windows 10 Universal App Platform, in addition to the full .NET Framework.
While it may seem like we could upgrade the message transport using the new client library, that’s not going to be possible. The new client is not yet fully featured enough to build a capable message transport, let alone achieve feature parity with the functionality that currently exists in the Azure Service Bus transport. Indeed, Microsoft’s new client library is a complete rewrite—there isn’t a single API that hasn’t changed in some way.
Perhaps most importantly, the new client does not support transactional semantics. This means that atomic sends and receives, where outgoing messages are only truly sent if the incoming message is processed successfully, are not possible with the new client.
This lack of transactional semantics alone prevents us from immediately delivering a .NET Core version of our Azure Service Bus transport.
Complicating things even further, the new Azure Service Bus client isn’t wire-compatible with the old client. In the new client, Microsoft has removed the serialization that was baked into the old client. This is a positive change but a breaking one. Workarounds are possible, but they’re problematic. That’s because it’s not possible to know if a destination endpoint will be using the old or new client. Every endpoint using both the old and new clients would need to be “bilingual” in order to understand all messages, no matter which client was used at their source. This makes it impossible to upgrade one endpoint at a time.
The new client also does not include any management operations, by design. Using the new client, it’s not possible to check if an entity (whether that be a queue, topic, or subscription) exists or to perform any sort of CRUD operation on it. These types of operations will need to be scripted when using the new client.
So what does all this mean for our Azure Service Bus transport?
The new deal
In the long term, the split in Azure Service Bus client libraries will be echoed by the creation of a new message transport, based on the new client library. Meanwhile, we’ll continue to support the existing transport.
We’ll update the NServiceBus.Azure.Transports.WindowsAzureServiceBus package to work with the next version of NServiceBus for the .NET Framework only, and continue to support this transport for customers that require transactional semantics. This transport will be supported without new features for the foreseeable future, as specified by our support policy.
We’re building a new Azure Service Bus transport that targets .NET Standard 2.0 using the new Azure Service Bus client. This transport won’t interoperate with the old transport, but we’ll provide a way to move messages from the old transport to the new transport.
We’ll release an alpha package as soon as possible that doesn’t contain support for transactional semantics, rather than wait for Microsoft to fully support the feature. This will allow you to experiment with the new transport and give us feedback.
Just as we waited until the release of .NET Core 2.0 to release NServiceBus for .NET Core, we want to wait until the appropriate time to release an Azure Service Bus transport for .NET Core. It’s not a question of if, but when, which will be dictated by the maturity of the new client.
If you have an Azure Service Bus project and you’re itching to make a move to .NET Core, let us know! We’d love to stay in contact with you or get you involved in beta testing for the new transport before it’s fully released. Send us an email at email@example.com and we’ll keep you in the loop.