Skip to content

Commit 75e4955

Browse files
Fix API version enum collisions in multservice clients (#10108)
PR #10061 unconditionally used the full namespace for API version enum names in multi-service scenarios. This produces unnecessarily verbose names when services have distinct last namespace segments. This PR changes the logic to only use the full namespace when there's an actual collision, and restores the `ClientHelper.BuildNameForService` helper for proper prefix/suffix-aware naming. The collision-aware naming applies to all multi-service generated members — enum type names, version property names, and latest version field names all use `BuildNameForService` by default, falling back to a segment-by-segment resolution when last segments collide. The enum type naming follows the `{X}ServiceVersion` pattern (e.g., `KeyVaultServiceVersion`) rather than `Service{X}Version`. When last segments collide, the new `ClientHelper.GetShortestUniqueNamespacePrefix` method progressively adds namespace segments from right to left until a unique suffix is found, producing shorter names than the previous full-namespace approach. When multiple enums share the exact same full namespace (e.g., when the emitter remaps both services to the same C# output namespace), the enum's input name is appended for disambiguation to prevent duplicate member names. ### Behavior | Namespaces | Member | Before (PR #10061) | After (no collision) | After (last segment collision) | After (full namespace collision) | |---|---|---|---|---|---| | `Sample.KeyVault`, `Sample.Storage` | Enum type | `SampleKeyVaultVersion` | `KeyVaultServiceVersion` | — | — | | `Sample.KeyVault`, `Sample.Storage` | Version property | `SampleKeyVaultApiVersion` | `KeyVaultApiVersion` | — | — | | `Sample.KeyVault`, `Sample.Storage` | Latest field | `LatestServiceKeyVaultVersion` | `LatestKeyVaultVersion` | — | — | | `Azure.One.Tests`, `Azure.Two.Tests` | Enum type | `AzureOneTestsVersion` | — | `ServiceOneTestsVersion` (shortest unique: 2 segments) | — | | `Azure.One.Tests`, `Azure.Two.Tests` | Version property | `AzureOneTestsApiVersion` | — | `ServiceOneTestsApiVersion` (shortest unique: 2 segments) | — | | Same namespace for both enums | Enum type | — | — | — | `{Namespace}{EnumName}Version` (disambiguated by input name) | ### Changes - **`ClientHelper.cs`** — restored `BuildNameForService` helper (removed in PR #10061) that extracts the last namespace segment and ensures proper prefix/suffix without duplication; added shared `GetLastNamespaceSegment` and `HasLastSegmentCollision` static helpers; added `GetShortestUniqueNamespacePrefix` that progressively adds segments from right to left until finding a unique suffix, falling back to appending the enum input name when namespaces are identical - **`ClientHelperTests.cs`** — restored all 22 tests for `BuildNameForService` - **`ApiVersionEnumProvider.BuildName()`** — uses `ClientHelper.BuildNameForService` with empty prefix and `"ServiceVersion"` suffix for the non-collision case, producing `{X}ServiceVersion` names; uses `GetShortestUniqueNamespacePrefix` for segment-by-segment resolution when last segments collide - **`ClientOptionsProvider.BuildVersionProperties()`** — uses `ClientHelper.BuildNameForService` for version property names in the non-collision case; uses `GetShortestUniqueNamespacePrefix` when last segments collide - **`ClientOptionsProvider.BuildLatestVersionsFields()`** — uses `ClientHelper.BuildNameForService` for latest version field names in the non-collision case; uses `GetShortestUniqueNamespacePrefix` when last segments collide - **Tests** — updated assertions and expected test data files (ClientOptionsProvider, ClientProvider, RestClientProvider) for member name changes; added `MultiServiceClient_WithCollidingLastSegments_UsesShortestUniquePrefix` test with TestData golden file validation; added `MultiServiceClient_SameLastSegment_ProducesUniqueVersionEnums` test; added `MultiServiceClient_UniqueNamespaces_ProducesUniqueVersionEnums` test simulating distinct service namespaces; added `MultiServiceClient_SameNamespace_ProducesUniqueVersionEnums` test for the same-namespace scenario where the emitter remaps both services to the same C# output namespace <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Only Use Full Namespace for Api Version Enum When There are Conflicts</issue_title> > <issue_description>Follow up to #10061. > > This PR introduced a change to avoid collisions in the generated api version enums in the multi-service scenario by using the full namespace of the enum as the name. We should update this to only do this whenever there is a collision in the generated names.</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes #10107 <!-- START COPILOT CODING AGENT TIPS --> --- 📱 Kick off Copilot coding agent tasks wherever you are with [GitHub Mobile](https://gh.io/cca-mobile-docs), available on iOS and Android. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jorgerangel-msft <102122018+jorgerangel-msft@users.noreply.github.com>
1 parent 096443e commit 75e4955

22 files changed

Lines changed: 905 additions & 150 deletions

File tree

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientOptionsProvider.cs

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Microsoft.TypeSpec.Generator.Providers;
1313
using Microsoft.TypeSpec.Generator.Snippets;
1414
using Microsoft.TypeSpec.Generator.Statements;
15+
using Microsoft.TypeSpec.Generator.Shared;
1516
using Microsoft.TypeSpec.Generator.Utilities;
1617
using static Microsoft.TypeSpec.Generator.Snippets.Snippet;
1718

@@ -123,7 +124,7 @@ private static bool UseSingletonInstance(InputClient inputClient)
123124

124125
internal IReadOnlyDictionary<EnumProvider, PropertyProvider>? VersionProperties => field ??= BuildVersionProperties();
125126

126-
private Dictionary<EnumProvider, PropertyProvider>? BuildVersionProperties()
127+
private Dictionary<EnumProvider, PropertyProvider>? BuildVersionProperties()
127128
{
128129
if (_serviceVersionsEnums is null)
129130
{
@@ -133,11 +134,26 @@ private static bool UseSingletonInstance(InputClient inputClient)
133134
var properties = new Dictionary<EnumProvider, PropertyProvider>(_serviceVersionsEnums.Count);
134135
foreach (var (inputEnum, enumProvider) in _serviceVersionsEnums)
135136
{
136-
// For multi-service clients, use the full namespace to guarantee uniqueness
137-
// (the last segment alone can collide when services share a namespace).
138-
var versionPropertyName = _inputClient.IsMultiServiceClient
139-
? $"{inputEnum.Namespace.ToIdentifierName()}{ApiVersionSuffix}"
140-
: VersionSuffix;
137+
string versionPropertyName;
138+
if (!_inputClient.IsMultiServiceClient)
139+
{
140+
versionPropertyName = VersionSuffix;
141+
}
142+
else
143+
{
144+
var serviceNamespace = inputEnum.Namespace;
145+
if (!string.IsNullOrEmpty(serviceNamespace) &&
146+
ClientHelper.HasLastSegmentCollision(serviceNamespace, inputEnum, _serviceVersionsEnums.Keys))
147+
{
148+
// Last segment collides — find the shortest unique namespace suffix.
149+
string uniquePrefix = ClientHelper.GetShortestUniqueNamespacePrefix(serviceNamespace, inputEnum, _serviceVersionsEnums.Keys);
150+
versionPropertyName = $"{uniquePrefix.ToIdentifierName()}{ApiVersionSuffix}";
151+
}
152+
else
153+
{
154+
versionPropertyName = ClientHelper.BuildNameForService(serviceNamespace ?? string.Empty, string.Empty, ApiVersionSuffix);
155+
}
156+
}
141157

142158
var versionProperty = new PropertyProvider(
143159
null,
@@ -161,11 +177,28 @@ private static bool UseSingletonInstance(InputClient inputClient)
161177
}
162178

163179
Dictionary<FieldProvider, EnumProvider> latestVersionFields = new(_serviceVersionsEnums.Count);
164-
foreach (var enumProvider in _serviceVersionsEnums.Values)
180+
foreach (var (inputEnum, enumProvider) in _serviceVersionsEnums)
165181
{
166-
var fieldName = _inputClient.IsMultiServiceClient
167-
? $"{LatestPrefix}{enumProvider.Name.ToIdentifierName()}"
168-
: LatestVersionFieldName;
182+
string fieldName;
183+
if (!_inputClient.IsMultiServiceClient)
184+
{
185+
fieldName = LatestVersionFieldName;
186+
}
187+
else
188+
{
189+
var serviceNamespace = inputEnum.Namespace;
190+
if (!string.IsNullOrEmpty(serviceNamespace) &&
191+
ClientHelper.HasLastSegmentCollision(serviceNamespace, inputEnum, _serviceVersionsEnums.Keys))
192+
{
193+
// Last segment collides — find the shortest unique namespace suffix.
194+
string uniquePrefix = ClientHelper.GetShortestUniqueNamespacePrefix(serviceNamespace, inputEnum, _serviceVersionsEnums.Keys);
195+
fieldName = $"{LatestPrefix}{uniquePrefix.ToIdentifierName()}{VersionSuffix}";
196+
}
197+
else
198+
{
199+
fieldName = ClientHelper.BuildNameForService(serviceNamespace ?? string.Empty, LatestPrefix, VersionSuffix);
200+
}
201+
}
169202
var field = new FieldProvider(
170203
modifiers: FieldModifiers.Private | FieldModifiers.Const,
171204
type: enumProvider.Type,

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientOptionsProviderTests.cs

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,163 @@ public void MultiServiceClient_SameLastSegment_ProducesUniqueVersionEnums()
752752
var nestedTypes = clientOptionsProvider!.NestedTypes;
753753
Assert.AreEqual(2, nestedTypes.Count);
754754
CollectionAssert.AllItemsAreUnique(nestedTypes.Select(t => t.Name).ToList());
755+
756+
var writer = new TypeProviderWriter(clientOptionsProvider!);
757+
var file = writer.Write();
758+
759+
Assert.AreEqual(Helpers.GetExpectedFromFile(), file.Content);
760+
}
761+
762+
[Test]
763+
public void MultiServiceClient_UniqueNamespaces_ProducesUniqueVersionEnums()
764+
{
765+
List<string> serviceOneVersions = ["2024-01-01"];
766+
List<string> serviceTwoVersions = ["2024-06-01"];
767+
768+
var serviceOneEnumValues = serviceOneVersions.Select(a => (a, a));
769+
var serviceTwoEnumValues = serviceTwoVersions.Select(a => (a, a));
770+
771+
var serviceOneEnum = InputFactory.StringEnum(
772+
"Versions",
773+
serviceOneEnumValues,
774+
usage: InputModelTypeUsage.ApiVersionEnum,
775+
clientNamespace: "ServiceOne");
776+
var serviceTwoEnum = InputFactory.StringEnum(
777+
"Versions",
778+
serviceTwoEnumValues,
779+
usage: InputModelTypeUsage.ApiVersionEnum,
780+
clientNamespace: "ServiceTwo");
781+
782+
InputParameter apiVersionParameter = InputFactory.QueryParameter(
783+
"apiVersion",
784+
InputPrimitiveType.String,
785+
isRequired: true,
786+
scope: InputParameterScope.Client,
787+
isApiVersion: true);
788+
789+
var serviceOneOperation = InputFactory.Operation(
790+
"ServiceOneOperation",
791+
parameters: [apiVersionParameter],
792+
ns: "ServiceOne");
793+
794+
var serviceTwoOperation = InputFactory.Operation(
795+
"ServiceTwoOperation",
796+
parameters: [apiVersionParameter],
797+
ns: "ServiceTwo");
798+
799+
var client = InputFactory.Client(
800+
"MultiServiceClient",
801+
methods:
802+
[
803+
InputFactory.BasicServiceMethod("ServiceOneMethod", serviceOneOperation),
804+
InputFactory.BasicServiceMethod("ServiceTwoMethod", serviceTwoOperation)
805+
],
806+
parameters: [apiVersionParameter],
807+
isMultiServiceClient: true);
808+
809+
MockHelpers.LoadMockGenerator(
810+
apiVersions: () => [.. serviceOneVersions, .. serviceTwoVersions],
811+
clients: () => [client],
812+
inputEnums: () => [serviceOneEnum, serviceTwoEnum]);
813+
814+
var clientProvider = ScmCodeModelGenerator.Instance.TypeFactory.CreateClient(client);
815+
Assert.IsNotNull(clientProvider);
816+
817+
// Validate that Fields access does not crash (the original issue crashed here)
818+
Assert.DoesNotThrow(() => _ = clientProvider!.Fields);
819+
820+
// Validate that Methods access does not crash (original crash site: Fields.ToDictionary in BuildMethods)
821+
Assert.DoesNotThrow(() => _ = clientProvider!.Methods);
822+
823+
var clientOptionsProvider = clientProvider?.ClientOptions;
824+
Assert.IsNotNull(clientOptionsProvider);
825+
826+
// Validate nested service version enums have unique names
827+
var nestedTypes = clientOptionsProvider!.NestedTypes;
828+
Assert.AreEqual(2, nestedTypes.Count);
829+
CollectionAssert.AllItemsAreUnique(nestedTypes.Select(t => t.Name).ToList());
830+
831+
// Verify enum names follow the XServiceVersion pattern
832+
Assert.AreEqual("ServiceOneServiceVersion", nestedTypes[0].Name);
833+
Assert.AreEqual("ServiceTwoServiceVersion", nestedTypes[1].Name);
834+
835+
var writer = new TypeProviderWriter(clientOptionsProvider!);
836+
var file = writer.Write();
837+
Assert.AreEqual(Helpers.GetExpectedFromFile(), file.Content);
838+
}
839+
840+
[Test]
841+
public void MultiServiceClient_SameNamespace_ProducesUniqueVersionEnums()
842+
{
843+
// Regression test for the scenario where both enums share the exact same namespace
844+
// (e.g., when tspconfig remaps both services to the same C# output namespace).
845+
List<string> serviceOneVersions = ["2024-01-01"];
846+
List<string> serviceTwoVersions = ["2024-06-01"];
847+
848+
var serviceOneEnumValues = serviceOneVersions.Select(a => (a, a));
849+
var serviceTwoEnumValues = serviceTwoVersions.Select(a => (a, a));
850+
851+
// Both enums have the EXACT SAME namespace (simulates tspconfig namespace override)
852+
var serviceOneEnum = InputFactory.StringEnum(
853+
"ServiceOneVersions",
854+
serviceOneEnumValues,
855+
usage: InputModelTypeUsage.ApiVersionEnum,
856+
clientNamespace: "Azure.Generator.MgmtTypeSpec.MultiService.Tests");
857+
var serviceTwoEnum = InputFactory.StringEnum(
858+
"ServiceTwoVersions",
859+
serviceTwoEnumValues,
860+
usage: InputModelTypeUsage.ApiVersionEnum,
861+
clientNamespace: "Azure.Generator.MgmtTypeSpec.MultiService.Tests");
862+
863+
InputParameter apiVersionParameter = InputFactory.QueryParameter(
864+
"apiVersion",
865+
InputPrimitiveType.String,
866+
isRequired: true,
867+
scope: InputParameterScope.Client,
868+
isApiVersion: true);
869+
870+
var serviceOneOperation = InputFactory.Operation(
871+
"ServiceOneOperation",
872+
parameters: [apiVersionParameter],
873+
ns: "Azure.Generator.MgmtTypeSpec.MultiService.Tests");
874+
875+
var serviceTwoOperation = InputFactory.Operation(
876+
"ServiceTwoOperation",
877+
parameters: [apiVersionParameter],
878+
ns: "Azure.Generator.MgmtTypeSpec.MultiService.Tests");
879+
880+
var client = InputFactory.Client(
881+
"MultiServiceClient",
882+
methods:
883+
[
884+
InputFactory.BasicServiceMethod("ServiceOneMethod", serviceOneOperation),
885+
InputFactory.BasicServiceMethod("ServiceTwoMethod", serviceTwoOperation)
886+
],
887+
parameters: [apiVersionParameter],
888+
isMultiServiceClient: true);
889+
890+
MockHelpers.LoadMockGenerator(
891+
apiVersions: () => [.. serviceOneVersions, .. serviceTwoVersions],
892+
clients: () => [client],
893+
inputEnums: () => [serviceOneEnum, serviceTwoEnum]);
894+
895+
var clientProvider = ScmCodeModelGenerator.Instance.TypeFactory.CreateClient(client);
896+
Assert.IsNotNull(clientProvider);
897+
898+
Assert.DoesNotThrow(() => _ = clientProvider!.Fields);
899+
Assert.DoesNotThrow(() => _ = clientProvider!.Methods);
900+
901+
var clientOptionsProvider = clientProvider?.ClientOptions;
902+
Assert.IsNotNull(clientOptionsProvider);
903+
904+
// Validate nested service version enums have unique names
905+
var nestedTypes = clientOptionsProvider!.NestedTypes;
906+
Assert.AreEqual(2, nestedTypes.Count);
907+
CollectionAssert.AllItemsAreUnique(nestedTypes.Select(t => t.Name).ToList());
908+
909+
var writer = new TypeProviderWriter(clientOptionsProvider!);
910+
var file = writer.Write();
911+
Assert.AreEqual(Helpers.GetExpectedFromFile(), file.Content);
755912
}
756913

757914
[Test]

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3678,12 +3678,12 @@ public void GetApiVersionFieldForService_MultiService_ReturnsMatchingField()
36783678
// Should return the matching field for ServiceA
36793679
var fieldA = clientProvider!.GetApiVersionFieldForService("Sample.ServiceA");
36803680
Assert.IsNotNull(fieldA);
3681-
Assert.AreEqual("_sampleServiceAApiVersion", fieldA!.Name);
3681+
Assert.AreEqual("_serviceAApiVersion", fieldA!.Name);
36823682

36833683
// Should return the matching field for ServiceB
36843684
var fieldB = clientProvider.GetApiVersionFieldForService("Sample.ServiceB");
36853685
Assert.IsNotNull(fieldB);
3686-
Assert.AreEqual("_sampleServiceBApiVersion", fieldB!.Name);
3686+
Assert.AreEqual("_serviceBApiVersion", fieldB!.Name);
36873687
}
36883688

36893689
[Test]
@@ -3814,11 +3814,11 @@ public void GetApiVersionFieldForService_MultiService_CaseInsensitiveMatch()
38143814
// Should match case-insensitively
38153815
var fieldLowerCase = clientProvider!.GetApiVersionFieldForService("sample.serviceA");
38163816
Assert.IsNotNull(fieldLowerCase);
3817-
Assert.AreEqual("_sampleServiceAApiVersion", fieldLowerCase!.Name);
3817+
Assert.AreEqual("_serviceAApiVersion", fieldLowerCase!.Name);
38183818

38193819
var fieldUpperCase = clientProvider.GetApiVersionFieldForService("SAMPLE.SERVICEa");
38203820
Assert.IsNotNull(fieldUpperCase);
3821-
Assert.AreEqual("_sampleServiceAApiVersion", fieldUpperCase!.Name);
3821+
Assert.AreEqual("_serviceAApiVersion", fieldUpperCase!.Name);
38223822
}
38233823

38243824
[Test]
@@ -3883,17 +3883,17 @@ public void GetApiVersionFieldForService_MultiService_SameLastSegment_ProducesUn
38833883
// This should not crash — previously it threw due to duplicate field names
38843884
Assert.DoesNotThrow(() => _ = clientProvider!.Fields);
38853885

3886-
// Verify we have two distinct api version fields using the full namespace
3886+
// Verify we have two distinct api version fields using the shortest unique namespace suffix
38873887
var apiVersionFields = clientProvider!.Fields
38883888
.Where(f => f.Name.Contains("ApiVersion", StringComparison.OrdinalIgnoreCase))
38893889
.OrderBy(f => f.Name)
38903890
.ToList();
38913891
Assert.AreEqual(2, apiVersionFields.Count);
38923892
Assert.AreNotEqual(apiVersionFields[0].Name, apiVersionFields[1].Name);
38933893

3894-
// Full namespace produces unique names: "Azure.ServiceOne.Tests" → "AzureServiceOneTests"
3895-
Assert.AreEqual("_azureServiceOneTestsApiVersion", apiVersionFields[0].Name);
3896-
Assert.AreEqual("_azureServiceTwoTestsApiVersion", apiVersionFields[1].Name);
3894+
// Shortest unique suffix: "ServiceOne.Tests" → "ServiceOneTests"
3895+
Assert.AreEqual("_serviceOneTestsApiVersion", apiVersionFields[0].Name);
3896+
Assert.AreEqual("_serviceTwoTestsApiVersion", apiVersionFields[1].Name);
38973897
}
38983898

38993899
[TestCase("{endpoint}")]

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceClient_GeneratesExpectedClient.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public partial class TestClient
1414
{
1515
private readonly global::System.Uri _endpoint;
1616
private readonly string _subscriptionId;
17-
private readonly string _sampleServiceAApiVersion;
18-
private readonly string _sampleServiceBApiVersion;
17+
private readonly string _serviceAApiVersion;
18+
private readonly string _serviceBApiVersion;
1919
private global::Sample.ServiceA.ServiceA _cachedServiceA;
2020
private global::Sample.ServiceB.ServiceB _cachedServiceB;
2121

@@ -44,8 +44,8 @@ internal TestClient(global::System.ClientModel.Primitives.AuthenticationPolicy a
4444
{
4545
Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty<global::System.ClientModel.Primitives.PipelinePolicy>(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty<global::System.ClientModel.Primitives.PipelinePolicy>());
4646
}
47-
_sampleServiceAApiVersion = options.SampleServiceAApiVersion;
48-
_sampleServiceBApiVersion = options.SampleServiceBApiVersion;
47+
_serviceAApiVersion = options.ServiceAApiVersion;
48+
_serviceBApiVersion = options.ServiceBApiVersion;
4949
}
5050

5151
public TestClient(global::System.Uri endpoint, string subscriptionId, global::Sample.TestClientOptions options) : this(null, endpoint, subscriptionId, options)
@@ -56,12 +56,12 @@ public TestClient(global::System.Uri endpoint, string subscriptionId, global::Sa
5656

5757
public virtual global::Sample.ServiceA.ServiceA GetServiceAClient()
5858
{
59-
return (global::System.Threading.Volatile.Read(ref _cachedServiceA) ?? (global::System.Threading.Interlocked.CompareExchange(ref _cachedServiceA, new global::Sample.ServiceA.ServiceA(Pipeline, _endpoint, _sampleServiceAApiVersion, _subscriptionId), null) ?? _cachedServiceA));
59+
return (global::System.Threading.Volatile.Read(ref _cachedServiceA) ?? (global::System.Threading.Interlocked.CompareExchange(ref _cachedServiceA, new global::Sample.ServiceA.ServiceA(Pipeline, _endpoint, _serviceAApiVersion, _subscriptionId), null) ?? _cachedServiceA));
6060
}
6161

6262
public virtual global::Sample.ServiceB.ServiceB GetServiceBClient()
6363
{
64-
return (global::System.Threading.Volatile.Read(ref _cachedServiceB) ?? (global::System.Threading.Interlocked.CompareExchange(ref _cachedServiceB, new global::Sample.ServiceB.ServiceB(Pipeline, _endpoint, _sampleServiceBApiVersion, _subscriptionId), null) ?? _cachedServiceB));
64+
return (global::System.Threading.Volatile.Read(ref _cachedServiceB) ?? (global::System.Threading.Interlocked.CompareExchange(ref _cachedServiceB, new global::Sample.ServiceB.ServiceB(Pipeline, _endpoint, _serviceBApiVersion, _subscriptionId), null) ?? _cachedServiceB));
6565
}
6666
}
6767
}

0 commit comments

Comments
 (0)