using System.Threading; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace DysonNetwork.Shared.Registry; public interface IGrpcClientFactory where TClient : class { TClient CreateClient(); } public class LazyGrpcClientFactory( IServiceProvider serviceProvider, ILogger> logger ) : IGrpcClientFactory where TClient : class { private TClient? _client; private readonly Lock _lock = new(); public TClient CreateClient() { if (Volatile.Read(ref _client) != null) { return Volatile.Read(ref _client)!; } lock (_lock) { if (Volatile.Read(ref _client) != null) { return Volatile.Read(ref _client)!; } var client = serviceProvider.GetRequiredService(); Volatile.Write(ref _client, client); logger.LogInformation("Lazy initialized gRPC client: {ClientType}", typeof(TClient).Name); return Volatile.Read(ref _client)!; } } } public static class GrpcClientFactoryExtensions { public static IServiceCollection AddLazyGrpcClientFactory(this IServiceCollection services) where TClient : class { services.AddScoped>(); services.AddScoped>(sp => sp.GetRequiredService>()); return services; } }