using System.Reflection; using BackOffice.BFF.Application.Common.Interfaces; using Grpc.Core; using System.Net.Http; using Grpc.Net.ClientFactory; using Microsoft.Extensions.Configuration; namespace Microsoft.Extensions.DependencyInjection; public static class ConfigureGrpcServices { public static IServiceCollection BatchRegisterGrpcClients(this IServiceCollection services, IConfiguration configuration) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); var grpcClients = assemblies .Where(x => x.FullName != null && (x.FullName.Contains("Microservice.Protobuf") || x.FullName.Contains("BackOffice.BFF.Commission.Protobuf") || x.FullName.Contains("BackOffice.BFF.NetworkMembership.Protobuf") || x.FullName.Contains("BackOffice.BFF.ClubMembership.Protobuf") || x.FullName.Contains("BackOffice.BFF.Configuration.Protobuf")) && x.GetTypes().Any(type => type.BaseType != null && type.BaseType.Name == "ClientBase`1" && type.BaseType.Namespace == "Grpc.Core") ) .SelectMany(x => x .GetTypes() .Where(type => type.BaseType != null && type.BaseType.Name == "ClientBase`1" && type.BaseType.Namespace == "Grpc.Core").ToList() ).ToList(); // get configuration as dictionary var clientAddress = configuration.GetSection("GrpcChannelOptions") .GetChildren().ToDictionary(x => x.Key, x => x.Value); // get register method var method = typeof(GrpcClientServiceExtensions).GetMethod("AddGrpcClient", new[] { typeof(IServiceCollection), typeof(string), typeof(Action) }); var httpHandler = new HttpClientHandler(); //TODO: چک شود // Return `true` to allow certificates that are untrusted/invalid httpHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; // register clients foreach (var (key, address) in clientAddress) { var msName = key.Replace("MSAddress", ""); // loop over clients foreach (var grpcClient in grpcClients.Where(t => t.AssemblyQualifiedName != null && (t.AssemblyQualifiedName.StartsWith($"{msName}Microservice") || t.AssemblyQualifiedName.StartsWith("Foursat.BackOffice.BFF.Commission") || t.AssemblyQualifiedName.StartsWith("Foursat.BackOffice.BFF.NetworkMembership") || t.AssemblyQualifiedName.StartsWith("Foursat.BackOffice.BFF.ClubMembership") || t.AssemblyQualifiedName.StartsWith("Foursat.BackOffice.BFF.Configuration")) ) .ToList()) { // make generic method with parameter var generic = method?.MakeGenericMethod(grpcClient); Console.WriteLine($"Registering {grpcClient.Name} of {msName} to {address}"); //if (grpcClient.Name == "PublicMessageContractClient") // continue; // invoke method with parameters var callResult = generic?.Invoke(null, new object[] { services,$"{grpcClient.Namespace}",(GrpcClientFactoryOptions o) => { o.Address = new Uri(address); } }); if (callResult == null) { Console.WriteLine($"Error registering {grpcClient.Name} of {msName} to {address}"); continue; } ((IHttpClientBuilder)callResult) .AddCallCredentials(CallCredentials) .ConfigureChannel(o => { o.HttpHandler = httpHandler; o.UnsafeUseInsecureChannelCallCredentials = true; o.MaxReceiveMessageSize = 1000 * 1024 * 1024; // 1 GB o.MaxSendMessageSize = 1000 * 1024 * 1024; // 1 GB }); } } return services; } public static IServiceCollection AddInfrastructureGrpcServices(this IServiceCollection services, IConfiguration configuration) { services.BatchRegisterGrpcClients(configuration); return services; } private static async Task CallCredentials(AuthInterceptorContext context, Metadata metadata, IServiceProvider serviceProvider) { var provider = serviceProvider.GetRequiredService(); var token = await provider.GetTokenAsync(); metadata.Add("Authorization", $"Bearer {token}"); } }