From ab4f58bfd0c290e40ccbc4648dccb609ef734891 Mon Sep 17 00:00:00 2001 From: lukaszgrzybowski Date: Sun, 12 Oct 2025 15:37:40 +0200 Subject: [PATCH 1/6] Simplify endpoint extraction in ConnectionSettings --- .../Configuration/ClientOptions.cs | 2 + .../Configuration/ConnectionSettings.cs | 40 ++----------------- .../Extensions/ClientOptionsExtensions.cs | 1 + .../Configuration/IClientOptions.cs | 3 ++ .../Configuration/ServiceBusSettings.cs | 1 + .../ConnectionSettingsComparer.cs | 5 +-- .../Management/Factories/ClientFactory.cs | 2 +- .../Management/Factories/IClientFactory.cs | 2 +- .../Management/ServiceBusRegistry.cs | 1 + .../Wrappers/ComposedReceiverOptions.cs | 1 + .../FailingClientFactory.cs | 2 +- .../FakeClientFactory.cs | 2 +- .../ServiceBusClientMock.cs | 2 +- .../DispatchConfigurationTest.cs | 10 +++-- .../ReceptionConfigurationTest.cs | 5 ++- .../Configuration/ServiceBusSettingsTests.cs | 5 ++- tests/Ev.ServiceBus.UnitTests/DispatchTest.cs | 22 +++++----- 17 files changed, 44 insertions(+), 62 deletions(-) diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs index 958590b..2631376 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ClientOptions.cs @@ -1,5 +1,7 @@ // ReSharper disable once CheckNamespace +using Ev.ServiceBus.Abstractions.Configuration; + namespace Ev.ServiceBus.Abstractions; public abstract class ClientOptions : IClientOptions diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs index a9f363c..4375127 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs @@ -1,7 +1,6 @@ -using System; -using Azure.Messaging.ServiceBus; +using Azure.Messaging.ServiceBus; -namespace Ev.ServiceBus.Abstractions; +namespace Ev.ServiceBus.Abstractions.Configuration; public class ConnectionSettings { @@ -9,40 +8,13 @@ internal ConnectionSettings(string connectionString, ServiceBusClientOptions opt { ConnectionString = connectionString; Options = options; - Endpoint = GetEndpointFromConnectionString(connectionString); + Endpoint = ServiceBusConnectionStringProperties.Parse(connectionString).Endpoint.AbsoluteUri; } public string Endpoint { get; } public string ConnectionString { get; } public ServiceBusClientOptions Options { get; } - private string GetEndpointFromConnectionString(string connectionString) - { - var KeyValuePairDelimiter = ';'; - var KeyValueSeparator = '='; - var EndpointConfigName = "Endpoint"; - - // First split based on ';' - var keyValuePairs = connectionString.Split(new[] { KeyValuePairDelimiter }, StringSplitOptions.RemoveEmptyEntries); - foreach (var keyValuePair in keyValuePairs) - { - // Now split based on the _first_ '=' - var keyAndValue = keyValuePair.Split(new[] { KeyValueSeparator }, 2); - var key = keyAndValue[0]; - if (keyAndValue.Length != 2) - { - return string.Empty; - } - - var value = keyAndValue[1].Trim(); - if (key.Equals(EndpointConfigName, StringComparison.OrdinalIgnoreCase)) - { - return value; - } - } - return string.Empty; - } - public override int GetHashCode() { return Endpoint.GetHashCode(); @@ -50,10 +22,6 @@ public override int GetHashCode() public override bool Equals(object? obj) { - if (obj is not ConnectionSettings settings) - { - return false; - } - return Endpoint.Equals(settings.Endpoint); + return obj is ConnectionSettings settings && Endpoint.Equals(settings.Endpoint); } } \ No newline at end of file diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs index 1c15222..20b0195 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs @@ -1,4 +1,5 @@ using Azure.Messaging.ServiceBus; +using Ev.ServiceBus.Abstractions.Configuration; // ReSharper disable once CheckNamespace namespace Ev.ServiceBus.Abstractions; diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs index 7eaf25d..0294a21 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/IClientOptions.cs @@ -1,4 +1,7 @@ // ReSharper disable once CheckNamespace + +using Ev.ServiceBus.Abstractions.Configuration; + namespace Ev.ServiceBus.Abstractions; public interface IClientOptions diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs index a490d4a..eb12de4 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs @@ -1,4 +1,5 @@ using Azure.Messaging.ServiceBus; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.Abstractions; diff --git a/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs b/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs index 3bed55b..5c0d312 100644 --- a/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs +++ b/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs @@ -1,6 +1,5 @@ -using System; -using System.Collections.Generic; -using Ev.ServiceBus.Abstractions; +using System.Collections.Generic; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.HealthChecks; diff --git a/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs b/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs index 8359fef..1dad203 100644 --- a/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs +++ b/src/Ev.ServiceBus/Management/Factories/ClientFactory.cs @@ -1,5 +1,5 @@ using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus; diff --git a/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs b/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs index 9231571..ac6b1fd 100644 --- a/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs +++ b/src/Ev.ServiceBus/Management/Factories/IClientFactory.cs @@ -1,5 +1,5 @@ using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; // ReSharper disable once CheckNamespace namespace Ev.ServiceBus; diff --git a/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs b/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs index ebfe19a..0c9f0fc 100644 --- a/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs +++ b/src/Ev.ServiceBus/Management/ServiceBusRegistry.cs @@ -3,6 +3,7 @@ using System.Linq; using Azure.Messaging.ServiceBus; using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; using Microsoft.Extensions.Options; namespace Ev.ServiceBus.Management; diff --git a/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs b/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs index a7a5c3b..27dc320 100644 --- a/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs +++ b/src/Ev.ServiceBus/Management/Wrappers/ComposedReceiverOptions.cs @@ -2,6 +2,7 @@ using System.Linq; using Azure.Messaging.ServiceBus; using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus; diff --git a/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs b/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs index f32e70d..4d54e59 100644 --- a/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs +++ b/tests/Ev.ServiceBus.TestHelpers/FailingClientFactory.cs @@ -1,6 +1,6 @@ using System; using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.UnitTests.Helpers; diff --git a/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs b/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs index ac892ce..36bd972 100644 --- a/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs +++ b/tests/Ev.ServiceBus.TestHelpers/FakeClientFactory.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.TestHelpers; diff --git a/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs b/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs index 16d181f..a9c080e 100644 --- a/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs +++ b/tests/Ev.ServiceBus.TestHelpers/ServiceBusClientMock.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; using Azure.Messaging.ServiceBus; -using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; using Moq; namespace Ev.ServiceBus.TestHelpers; diff --git a/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs b/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs index 35106af..3893942 100644 --- a/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs +++ b/tests/Ev.ServiceBus.UnitTests/Configuration/DispatchConfigurationTest.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Azure.Messaging.ServiceBus; using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; using Ev.ServiceBus.Management; using Ev.ServiceBus.UnitTests.Helpers; using FluentAssertions; @@ -362,17 +363,18 @@ public void SendToQueue_ArgumentCannotBeNull() public async Task CustomizeConnection_ChangesAreAppliedToClient() { var composer = new Composer(); - var serviceBusClientOptions = new ServiceBusClientOptions() + var serviceBusClientOptions = new ServiceBusClientOptions { EnableCrossEntityTransactions = true, TransportType = ServiceBusTransportType.AmqpWebSockets }; var factory = new Mock(); + const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc="; factory.Setup(o => o.Create(It.Is(settings => - settings.ConnectionString == "Endpoint=newConnectionString;" + settings.ConnectionString == connectionString && settings.Options == serviceBusClientOptions - && settings.Endpoint == "newConnectionString"))) + && settings.Endpoint == "sb://acmecompany.servicebus.windows.net/"))) .Returns(new Mock().Object); composer.WithAdditionalServices(services => @@ -380,7 +382,7 @@ public async Task CustomizeConnection_ChangesAreAppliedToClient() services.RegisterServiceBusDispatch() .ToTopic("testTopic", builder => { - builder.CustomizeConnection("Endpoint=newConnectionString;", serviceBusClientOptions); + builder.CustomizeConnection(connectionString, serviceBusClientOptions); builder.RegisterDispatch(); }); services.OverrideClientFactory(factory.Object); diff --git a/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs b/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs index c55238f..fe42bff 100644 --- a/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs +++ b/tests/Ev.ServiceBus.UnitTests/Configuration/ReceptionConfigurationTest.cs @@ -357,6 +357,7 @@ public async Task CustomizeMessageHandling_ChangesAreAppliedToClient() [Fact] public async Task CustomizeConnection_ChangesAreAppliedToClient() { + const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc="; var composer = new Composer(); composer.WithAdditionalServices(services => @@ -365,7 +366,7 @@ public async Task CustomizeConnection_ChangesAreAppliedToClient() .FromSubscription("testTopic", "testSubscription", builder => { - builder.CustomizeConnection("Endpoint=newConnectionString;", new ServiceBusClientOptions() + builder.CustomizeConnection(connectionString, new ServiceBusClientOptions { EnableCrossEntityTransactions = true, TransportType = ServiceBusTransportType.AmqpWebSockets @@ -376,7 +377,7 @@ public async Task CustomizeConnection_ChangesAreAppliedToClient() }); await composer.Compose(); - var client = composer.ClientFactory.GetAssociatedMock("newConnectionString"); + var client = composer.ClientFactory.GetAssociatedMock("sb://acmecompany.servicebus.windows.net/"); client.ConnectionSettings.Options.EnableCrossEntityTransactions.Should().Be(true); client.ConnectionSettings.Options.TransportType.Should().Be(ServiceBusTransportType.AmqpWebSockets); } diff --git a/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs b/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs index 1e3780e..ad60a02 100644 --- a/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs +++ b/tests/Ev.ServiceBus.UnitTests/Configuration/ServiceBusSettingsTests.cs @@ -29,18 +29,19 @@ public async Task ServiceBusSettingsStateByDefault() [Fact] public async Task ServiceBusSettingsStateAfterCallOfWithConnection_string() { + const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc="; var composer = new Composer(); composer.WithDefaultSettings( settings => { - settings.WithConnection("Endpoint=testConnectionString;", new ServiceBusClientOptions()); + settings.WithConnection(connectionString, new ServiceBusClientOptions()); }); var provider = await composer.Compose(); var options = provider.GetService>(); options.Value.Settings.ConnectionSettings.Should().NotBeNull(); - options.Value.Settings.ConnectionSettings!.Endpoint.Should().Be("testConnectionString"); + options.Value.Settings.ConnectionSettings!.Endpoint.Should().Be("sb://acmecompany.servicebus.windows.net/"); } } \ No newline at end of file diff --git a/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs b/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs index ef65051..1009089 100644 --- a/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs +++ b/tests/Ev.ServiceBus.UnitTests/DispatchTest.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -408,10 +407,11 @@ await Assert.ThrowsAsync( public async Task SendDispatch() { // configure + const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc="; var services = new ServiceCollection(); services.AddServiceBus(settings => { - settings.WithConnection("myConnection", new ServiceBusClientOptions()); + settings.WithConnection(connectionString, new ServiceBusClientOptions()); }); services.OverrideClientFactory(); services.RegisterServiceBusDispatch().ToQueue("myQueue", builder => @@ -447,10 +447,11 @@ public async Task SendDispatch() public async Task SendDispatchesPaginateMessages() { // configure + const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc="; var services = new ServiceCollection(); services.AddServiceBus(settings => { - settings.WithConnection("myConnection", new ServiceBusClientOptions()); + settings.WithConnection(connectionString, new ServiceBusClientOptions()); }); services.OverrideClientFactory(); services.RegisterServiceBusDispatch().ToQueue("myQueue", builder => @@ -458,14 +459,14 @@ public async Task SendDispatchesPaginateMessages() builder.RegisterDispatch(); }); var provider = services.BuildServiceProvider(); - await provider.SimulateStartHost(new CancellationToken()); + await provider.SimulateStartHost(CancellationToken.None); // Act var messages = new SubscribedEvent[10000]; int i = 0; while (i < 10000) { - messages[i] = new SubscribedEvent() + messages[i] = new SubscribedEvent { SomeNumber = i + 1, SomeString = $"Event number {i+1}" @@ -484,17 +485,18 @@ public async Task SendDispatchesPaginateMessages() mock.Mock.Verify(o => o.SendMessagesAsync(It.IsAny(), It.IsAny()), Times.Exactly(1)); // Dispose - await provider.SimulateStopHost(new CancellationToken()); + await provider.SimulateStopHost(CancellationToken.None); } [Fact] public async Task ScheduleDispatchesPaginateMessages() { // configure + const string connectionString = "Endpoint=sb://acmecompany.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=kFCrVU8u5v0LASbKGA3MHDpnCOguiNwL++r1cAvblhc="; var services = new ServiceCollection(); services.AddServiceBus(settings => { - settings.WithConnection("myConnection", new ServiceBusClientOptions()); + settings.WithConnection(connectionString, new ServiceBusClientOptions()); }); services.OverrideClientFactory(); services.RegisterServiceBusDispatch().ToQueue("myQueue", builder => @@ -502,14 +504,14 @@ public async Task ScheduleDispatchesPaginateMessages() builder.RegisterDispatch(); }); var provider = services.BuildServiceProvider(); - await provider.SimulateStartHost(new CancellationToken()); + await provider.SimulateStartHost(CancellationToken.None); // Act var messages = new SubscribedEvent[253]; int i = 0; while (i < 253) { - messages[i] = new SubscribedEvent() + messages[i] = new SubscribedEvent { SomeNumber = i + 1, SomeString = $"Event number {i+1}" @@ -530,7 +532,7 @@ public async Task ScheduleDispatchesPaginateMessages() mock.Mock.Verify(o => o.ScheduleMessagesAsync(It.IsAny>(), schedule, It.IsAny()), Times.Exactly(3)); // Dispose - await provider.SimulateStopHost(new CancellationToken()); + await provider.SimulateStopHost(CancellationToken.None); } [Fact] From bb1a39380535f2994e2d0e3c0298a88efabc35e1 Mon Sep 17 00:00:00 2001 From: lukaszgrzybowski Date: Sun, 12 Oct 2025 15:38:57 +0200 Subject: [PATCH 2/6] fix using in DocumentFilter file. --- src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs b/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs index 9acbdba..7bb0950 100644 --- a/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs +++ b/src/Ev.ServiceBus.AsyncApi/DocumentFilter.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text.Encodings.Web; -using System.Text.Json; using Ev.ServiceBus.Abstractions; +using Ev.ServiceBus.Abstractions.Configuration; using Microsoft.Extensions.Options; -using Microsoft.VisualBasic; using NJsonSchema; using Saunter.AsyncApiSchema.v2; using Saunter.AsyncApiSchema.v2.Bindings; @@ -117,7 +115,7 @@ private Operation CreatePublishOperation(string channelName, ClientOptions optio private IMessage GenerateMessage(string payloadTypeId, Type payloadType, DocumentFilterContext context, AsyncApiSchemaResolver asyncApiSchemaResolver) { - var message = new Saunter.AsyncApiSchema.v2.Message() + var message = new Message() { Name = payloadTypeId.Replace("/", "¤"), Payload = GetOrCreatePayloadSchema(payloadType, context), From 02d3fabcbcc6c4b6ce9f05e5b240942c77d23b1a Mon Sep 17 00:00:00 2001 From: lukaszgrzybowski Date: Fri, 14 Nov 2025 21:30:45 +0100 Subject: [PATCH 3/6] Corrected the assignment of the Endpoint and FullyQualifiedNamespace properties in the ConnectionSettings class. --- .../Configuration/ConnectionSettings.cs | 12 ++++-------- .../Extensions/ClientOptionsExtensions.cs | 2 +- .../Configuration/ServiceBusSettings.cs | 2 +- .../ConnectionSettingsComparer.cs | 3 ++- .../ComplexTest.cs | 4 ++-- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs index 3385b76..913d910 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs @@ -6,19 +6,15 @@ namespace Ev.ServiceBus.Abstractions.Configuration; public class ConnectionSettings { - internal ConnectionSettings(string connectionString, ServiceBusClientOptions options) + internal ConnectionSettings(string connectionString, ServiceBusClientOptions options, TokenCredential? credentials = null) { ConnectionString = connectionString; Options = options; Endpoint = ServiceBusConnectionStringProperties.Parse(connectionString).Endpoint.AbsoluteUri; - } - - internal ConnectionSettings(string fullyQualifiedNamespace, TokenCredential credentials, ServiceBusClientOptions options) - { - Options = options; - FullyQualifiedNamespace = fullyQualifiedNamespace; + FullyQualifiedNamespace = credentials == null + ? null + : ServiceBusConnectionStringProperties.Parse(connectionString).FullyQualifiedNamespace; Credentials = credentials; - Endpoint = ServiceBusConnectionStringProperties.Parse(fullyQualifiedNamespace).Endpoint.AbsoluteUri; } public string Endpoint { get; } diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs index 89876f1..a5d9f64 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs @@ -43,7 +43,7 @@ public static TOptions WithConnection( ServiceBusClientOptions connectionOptions) where TOptions : ClientOptions { - options.ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, credentials, connectionOptions); + options.ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, connectionOptions, credentials); return options; } } \ No newline at end of file diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs index 2cd3f28..a7dc025 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs @@ -39,7 +39,7 @@ public void WithConnection(string connectionString, ServiceBusClientOptions opti public void WithConnection(string fullyQualifiedNamespace, TokenCredential tokenCredential, ServiceBusClientOptions options) { - ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, tokenCredential, options); + ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, options, tokenCredential); } public void WithIsolation(IsolationBehavior behavior, string? isolationKey = null, string? applicationName = null) diff --git a/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs b/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs index 1db4e3f..8576fc9 100644 --- a/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs +++ b/src/Ev.ServiceBus.HealthChecks/ConnectionSettingsComparer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Ev.ServiceBus.Abstractions.Configuration; namespace Ev.ServiceBus.HealthChecks; diff --git a/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs b/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs index 8bf8ca2..aca0e8b 100644 --- a/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs +++ b/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs @@ -138,7 +138,7 @@ public void MultipleRegistrationsGoesWell_case4() services.AddServiceBus(settings => { - settings.WithConnection("Endpoint=testConnectionString;", new ServiceBusClientOptions()); + settings.WithConnection("Endpoint=acmecompany.servicebus.windows.net;", new ServiceBusClientOptions()); }); services.AddHealthChecks().AddEvServiceBusChecks(); @@ -174,7 +174,7 @@ public void HealthCheckWorksWithEntraAuthorization() services.AddServiceBus(settings => { - settings.WithConnection("fullyQualifiedNamespace", new DefaultAzureCredential(), new ServiceBusClientOptions()); + settings.WithConnection("Endpoint=acmecompany.servicebus.windows.net", new DefaultAzureCredential(), new ServiceBusClientOptions()); }); services.AddHealthChecks().AddEvServiceBusChecks(); From a60e092062609df63c99c02edf5b028f81e632f1 Mon Sep 17 00:00:00 2001 From: lukaszgrzybowski Date: Fri, 14 Nov 2025 21:34:30 +0100 Subject: [PATCH 4/6] Optimize parsing of connection string in ConnectionSettings constructor. --- .../Configuration/ConnectionSettings.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs index 913d910..1be41ef 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs @@ -8,12 +8,12 @@ public class ConnectionSettings { internal ConnectionSettings(string connectionString, ServiceBusClientOptions options, TokenCredential? credentials = null) { + var connectionStringProperties = ServiceBusConnectionStringProperties.Parse(connectionString); + ConnectionString = connectionString; Options = options; - Endpoint = ServiceBusConnectionStringProperties.Parse(connectionString).Endpoint.AbsoluteUri; - FullyQualifiedNamespace = credentials == null - ? null - : ServiceBusConnectionStringProperties.Parse(connectionString).FullyQualifiedNamespace; + Endpoint = connectionStringProperties.Endpoint.AbsoluteUri; + FullyQualifiedNamespace = credentials == null ? null : connectionStringProperties.FullyQualifiedNamespace; Credentials = credentials; } From 777c6317360793b2641be576289a21ee70ec0efa Mon Sep 17 00:00:00 2001 From: lukaszgrzybowski Date: Sun, 23 Nov 2025 14:46:50 +0100 Subject: [PATCH 5/6] Ensure connection string starts with 'Endpoint=' in ConnectionSettings --- .../Configuration/ConnectionSettings.cs | 5 +++++ tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs index 1be41ef..a8afb43 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs @@ -8,6 +8,11 @@ public class ConnectionSettings { internal ConnectionSettings(string connectionString, ServiceBusClientOptions options, TokenCredential? credentials = null) { + if (!connectionString.StartsWith("Endpoint=", StringComparison.OrdinalIgnoreCase)) + { + connectionString = $"Endpoint={connectionString}"; + } + var connectionStringProperties = ServiceBusConnectionStringProperties.Parse(connectionString); ConnectionString = connectionString; diff --git a/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs b/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs index aca0e8b..ef410d1 100644 --- a/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs +++ b/tests/Ev.ServiceBus.HealthChecks.UnitTests/ComplexTest.cs @@ -174,7 +174,7 @@ public void HealthCheckWorksWithEntraAuthorization() services.AddServiceBus(settings => { - settings.WithConnection("Endpoint=acmecompany.servicebus.windows.net", new DefaultAzureCredential(), new ServiceBusClientOptions()); + settings.WithConnection("acmecompany.servicebus.windows.net", new DefaultAzureCredential(), new ServiceBusClientOptions()); }); services.AddHealthChecks().AddEvServiceBusChecks(); From 4f4293d4d0df830f9f6f3a9aa81778b7caa9d52c Mon Sep 17 00:00:00 2001 From: lukaszgrzybowski Date: Mon, 24 Nov 2025 19:21:37 +0100 Subject: [PATCH 6/6] Restoring two constructors in ConnectionSettings --- .../Configuration/ConnectionSettings.cs | 20 ++++++++++++------- .../Extensions/ClientOptionsExtensions.cs | 2 +- .../Configuration/ServiceBusSettings.cs | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs index a8afb43..027053c 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ConnectionSettings.cs @@ -6,20 +6,26 @@ namespace Ev.ServiceBus.Abstractions.Configuration; public class ConnectionSettings { - internal ConnectionSettings(string connectionString, ServiceBusClientOptions options, TokenCredential? credentials = null) + internal ConnectionSettings(string connectionString, ServiceBusClientOptions options) { - if (!connectionString.StartsWith("Endpoint=", StringComparison.OrdinalIgnoreCase)) + ConnectionString = connectionString; + Options = options; + Endpoint = ServiceBusConnectionStringProperties.Parse(connectionString).Endpoint.AbsoluteUri; + } + + internal ConnectionSettings(string fullyQualifiedNamespace, TokenCredential credentials, ServiceBusClientOptions options) + { + if (!fullyQualifiedNamespace.StartsWith("Endpoint=", StringComparison.OrdinalIgnoreCase)) { - connectionString = $"Endpoint={connectionString}"; + fullyQualifiedNamespace = $"Endpoint={fullyQualifiedNamespace}"; } - var connectionStringProperties = ServiceBusConnectionStringProperties.Parse(connectionString); + var connectionStringProperties = ServiceBusConnectionStringProperties.Parse(fullyQualifiedNamespace); - ConnectionString = connectionString; Options = options; - Endpoint = connectionStringProperties.Endpoint.AbsoluteUri; - FullyQualifiedNamespace = credentials == null ? null : connectionStringProperties.FullyQualifiedNamespace; + FullyQualifiedNamespace = connectionStringProperties.FullyQualifiedNamespace; Credentials = credentials; + Endpoint = connectionStringProperties.Endpoint.AbsoluteUri; } public string Endpoint { get; } diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs index a5d9f64..89876f1 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/Extensions/ClientOptionsExtensions.cs @@ -43,7 +43,7 @@ public static TOptions WithConnection( ServiceBusClientOptions connectionOptions) where TOptions : ClientOptions { - options.ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, connectionOptions, credentials); + options.ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, credentials, connectionOptions); return options; } } \ No newline at end of file diff --git a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs index a7dc025..2cd3f28 100644 --- a/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs +++ b/src/Ev.ServiceBus.Abstractions/Configuration/ServiceBusSettings.cs @@ -39,7 +39,7 @@ public void WithConnection(string connectionString, ServiceBusClientOptions opti public void WithConnection(string fullyQualifiedNamespace, TokenCredential tokenCredential, ServiceBusClientOptions options) { - ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, options, tokenCredential); + ConnectionSettings = new ConnectionSettings(fullyQualifiedNamespace, tokenCredential, options); } public void WithIsolation(IsolationBehavior behavior, string? isolationKey = null, string? applicationName = null)