using Blazored.LocalStorage; using Grpc.Core; using Grpc.Net.Client.Web; using Grpc.Net.Client; using MudBlazor.Services; using System.Text.Json; using System.Text.Json.Serialization; using FrontOffice.BFF.Package.Protobuf.Protos.Package; using FrontOffice.BFF.User.Protobuf.Protos.User; using FrontOffice.BFF.UserAddress.Protobuf.Protos.UserAddress; using FrontOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; namespace Microsoft.Extensions.DependencyInjection; public static class ConfigureServices { public static IServiceCollection AddCommonServices(this IServiceCollection services) { services.AddMudServices(); services.AddBlazoredLocalStorage(config => { config.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase; config.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; config.JsonSerializerOptions.IgnoreReadOnlyProperties = true; config.JsonSerializerOptions.PropertyNameCaseInsensitive = true; config.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; config.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip; config.JsonSerializerOptions.WriteIndented = false; }); return services; } public static IServiceCollection AddGrpcServices(this IServiceCollection services, IConfiguration configuration) { var baseUrl = configuration["GwUrl"]; // Register HttpClient for gRPC services.AddScoped(sp => { var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler())); httpClient.Timeout = TimeSpan.FromMinutes(10); return httpClient; }); // Register gRPC clients as scoped services services.AddScoped(sp => { var httpClient = sp.GetRequiredService(); var localStorage = sp.GetRequiredService(); var credentials = CallCredentials.FromInterceptor(async (context, metadata) => { try { var token = await localStorage.GetItemAsync("auth:token"); if (!string.IsNullOrWhiteSpace(token)) { metadata.Add("Authorization", $"Bearer {token}"); } } catch (Exception) { // Ignore errors during token retrieval } }); var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions { UnsafeUseInsecureChannelCallCredentials = true, Credentials = ChannelCredentials.Create(new SslCredentials(), credentials), HttpClient = httpClient, MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB }); return new PackageContract.PackageContractClient(channel); }); services.AddScoped(sp => { var httpClient = sp.GetRequiredService(); var localStorage = sp.GetRequiredService(); var credentials = CallCredentials.FromInterceptor(async (context, metadata) => { try { var token = await localStorage.GetItemAsync("auth:token"); if (!string.IsNullOrWhiteSpace(token)) { metadata.Add("Authorization", $"Bearer {token}"); } } catch (Exception) { // Ignore errors during token retrieval } }); var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions { UnsafeUseInsecureChannelCallCredentials = true, Credentials = ChannelCredentials.Create(new SslCredentials(), credentials), HttpClient = httpClient, MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB }); return new UserContract.UserContractClient(channel); }); services.AddScoped(sp => { var httpClient = sp.GetRequiredService(); var localStorage = sp.GetRequiredService(); var credentials = CallCredentials.FromInterceptor(async (context, metadata) => { try { var token = await localStorage.GetItemAsync("auth:token"); if (!string.IsNullOrWhiteSpace(token)) { metadata.Add("Authorization", $"Bearer {token}"); } } catch (Exception) { // Ignore errors during token retrieval } }); var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions { UnsafeUseInsecureChannelCallCredentials = true, Credentials = ChannelCredentials.Create(new SslCredentials(), credentials), HttpClient = httpClient, MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB }); return new UserAddressContract.UserAddressContractClient(channel); }); services.AddScoped(sp => { var httpClient = sp.GetRequiredService(); var localStorage = sp.GetRequiredService(); var credentials = CallCredentials.FromInterceptor(async (context, metadata) => { try { var token = await localStorage.GetItemAsync("auth:token"); if (!string.IsNullOrWhiteSpace(token)) { metadata.Add("Authorization", $"Bearer {token}"); } } catch (Exception) { // Ignore errors during token retrieval } }); var channel = GrpcChannel.ForAddress(baseUrl, new GrpcChannelOptions { UnsafeUseInsecureChannelCallCredentials = true, Credentials = ChannelCredentials.Create(new SslCredentials(), credentials), HttpClient = httpClient, MaxReceiveMessageSize = 1000 * 1024 * 1024, // 1 GB MaxSendMessageSize = 1000 * 1024 * 1024 // 1 GB }); return new UserOrderContract.UserOrderContractClient(channel); }); return services; } }