Skip to content

Commit 3f9c94d

Browse files
unify the usage of lazy in ClientProvider (#5469)
Fixes #5470
1 parent 254aba7 commit 3f9c94d

File tree

1 file changed

+24
-25
lines changed
  • packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers

1 file changed

+24
-25
lines changed

packages/http-client-csharp/generator/Microsoft.Generator.CSharp.ClientModel/src/Providers/ClientProvider.cs

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,12 @@ private record OAuth2Fields(FieldProvider AuthField, FieldProvider Authorization
4141

4242
private FieldProvider? _apiVersionField;
4343
private readonly Lazy<IReadOnlyList<ParameterProvider>> _subClientInternalConstructorParams;
44-
private IReadOnlyList<Lazy<ClientProvider>>? _subClients;
44+
private readonly Lazy<IReadOnlyList<ClientProvider>> _subClients;
4545
private RestClientProvider? _restClient;
46-
private readonly InputParameter[] _allClientParameters;
47-
private Lazy<List<FieldProvider>> _additionalClientFields;
46+
private readonly IReadOnlyList<InputParameter> _allClientParameters;
47+
private Lazy<IReadOnlyList<FieldProvider>> _additionalClientFields;
4848

4949
private Lazy<ParameterProvider?> ClientOptionsParameter { get; }
50-
private IReadOnlyList<Lazy<ClientProvider>> SubClients => _subClients ??= GetSubClients();
5150

5251
// for mocking
5352
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
@@ -141,6 +140,7 @@ public ClientProvider(InputClient inputClient)
141140
_allClientParameters = _inputClient.Parameters.Concat(_inputClient.Operations.SelectMany(op => op.Parameters).Where(p => p.Kind == InputOperationParameterKind.Client)).DistinctBy(p => p.Name).ToArray();
142141
_subClientInternalConstructorParams = new(GetSubClientInternalConstructorParameters);
143142
_clientParameters = new(GetClientParameters);
143+
_subClients = new(GetSubClients);
144144
}
145145

146146
private IReadOnlyList<ParameterProvider> GetSubClientInternalConstructorParameters()
@@ -225,18 +225,18 @@ protected override FieldProvider[] BuildFields()
225225
fields.AddRange(_additionalClientFields.Value);
226226

227227
// add sub-client caching fields
228-
foreach (var subClient in SubClients)
228+
foreach (var subClient in _subClients.Value)
229229
{
230-
if (subClient.Value.Methods.Count != 0 && subClient.Value._clientCachingField != null)
230+
if (subClient.Methods.Count != 0 && subClient._clientCachingField != null)
231231
{
232-
fields.Add(subClient.Value._clientCachingField);
232+
fields.Add(subClient._clientCachingField);
233233
}
234234
}
235235

236236
return [.. fields];
237237
}
238238

239-
private List<FieldProvider> BuildAdditionalClientFields()
239+
private IReadOnlyList<FieldProvider> BuildAdditionalClientFields()
240240
{
241241
var fields = new List<FieldProvider>();
242242
// Add optional client parameters as fields
@@ -452,7 +452,8 @@ [.. primaryCtorOrderedParams.Select(p => p.InitializationValue ?? p)
452452

453453
protected override MethodProvider[] BuildMethods()
454454
{
455-
var subClientCount = SubClients.Count;
455+
var subClients = _subClients.Value;
456+
var subClientCount = subClients.Count;
456457
List<MethodProvider> methods = new List<MethodProvider>((_inputClient.Operations.Count * 4) + subClientCount);
457458

458459
// Build methods for all the operations
@@ -474,19 +475,18 @@ protected override MethodProvider[] BuildMethods()
474475
var parentClientFields = Fields.ToDictionary(f => f.Name.ToVariableName());
475476

476477
// Build factory accessor methods for the sub-clients
477-
foreach (var subClient in SubClients)
478+
foreach (var subClient in subClients)
478479
{
479-
var subClientInstance = subClient.Value;
480-
if (subClientInstance._clientCachingField is null || subClientInstance.Methods.Count == 0)
480+
if (subClient._clientCachingField is null || subClient.Methods.Count == 0)
481481
{
482482
continue;
483483
}
484484

485-
var cachedClientFieldVar = new VariableExpression(subClientInstance.Type, subClientInstance._clientCachingField.Declaration, IsRef: true);
485+
var cachedClientFieldVar = new VariableExpression(subClient.Type, subClient._clientCachingField.Declaration, IsRef: true);
486486
List<ValueExpression> subClientConstructorArgs = new(3);
487487

488488
// Populate constructor arguments
489-
foreach (var param in subClientInstance._subClientInternalConstructorParams.Value)
489+
foreach (var param in subClient._subClientInternalConstructorParams.Value)
490490
{
491491
if (parentClientProperties.TryGetValue(param.Name, out var parentProperty))
492492
{
@@ -501,23 +501,23 @@ protected override MethodProvider[] BuildMethods()
501501
// Create the interlocked compare exchange expression for the body
502502
var interlockedCompareExchange = Static(typeof(Interlocked)).Invoke(
503503
nameof(Interlocked.CompareExchange),
504-
[cachedClientFieldVar, New.Instance(subClientInstance.Type, subClientConstructorArgs), Null]);
505-
var factoryMethodName = subClient.Value.Name.EndsWith(ClientSuffix, StringComparison.OrdinalIgnoreCase)
506-
? $"Get{subClient.Value.Name}"
507-
: $"Get{subClient.Value.Name}{ClientSuffix}";
504+
[cachedClientFieldVar, New.Instance(subClient.Type, subClientConstructorArgs), Null]);
505+
var factoryMethodName = subClient.Name.EndsWith(ClientSuffix, StringComparison.OrdinalIgnoreCase)
506+
? $"Get{subClient.Name}"
507+
: $"Get{subClient.Name}{ClientSuffix}";
508508

509509
var factoryMethod = new MethodProvider(
510510
new(
511511
factoryMethodName,
512-
$"Initializes a new instance of {subClientInstance.Type.Name}",
512+
$"Initializes a new instance of {subClient.Type.Name}",
513513
MethodSignatureModifiers.Public | MethodSignatureModifiers.Virtual,
514-
subClientInstance.Type,
514+
subClient.Type,
515515
null,
516516
[]),
517517
// return Volatile.Read(ref _cachedClient) ?? Interlocked.CompareExchange(ref _cachedClient, new Client(_pipeline, _keyCredential, _endpoint), null) ?? _cachedClient;
518518
Return(
519519
Static(typeof(Volatile)).Invoke(nameof(Volatile.Read), cachedClientFieldVar)
520-
.NullCoalesce(interlockedCompareExchange.NullCoalesce(subClientInstance._clientCachingField))),
520+
.NullCoalesce(interlockedCompareExchange.NullCoalesce(subClient._clientCachingField))),
521521
this);
522522
methods.Add(factoryMethod);
523523
}
@@ -545,18 +545,17 @@ private ParameterProvider BuildClientEndpointParameter()
545545
};
546546
}
547547

548-
// TODO: Update method to be more efficient
549-
private IReadOnlyList<Lazy<ClientProvider>> GetSubClients()
548+
private IReadOnlyList<ClientProvider> GetSubClients()
550549
{
551550
var inputClients = ClientModelPlugin.Instance.InputLibrary.InputNamespace.Clients;
552-
var subClients = new List<Lazy<ClientProvider>>(inputClients.Count);
551+
var subClients = new List<ClientProvider>(inputClients.Count);
553552

554553
foreach (var client in inputClients)
555554
{
556555
// add direct child clients
557556
if (client.Parent != null && client.Parent == _inputClient.Key)
558557
{
559-
subClients.Add(new(() => ClientModelPlugin.Instance.TypeFactory.CreateClient(client)));
558+
subClients.Add(ClientModelPlugin.Instance.TypeFactory.CreateClient(client));
560559
}
561560
}
562561

0 commit comments

Comments
 (0)