Files
FrontOffice/src/FrontOffice.Main/ConfigureServices.cs
T
masoodafar-web 6db83ccd90
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 4m55s
feat: full FrontOffice updates - discount store, blog, payment gateway, UI improvements
- Discount store pages (products, cart, orders, order detail)
- Blog pages and services
- Payment gateway callback page
- AppImage component, EmptyState, LoadingState, PageHeader
- DiscountCartService, DiscountOrderService, DiscountProductService
- BlogCategoryService, BlogPostService, SitePageService, ImageCacheService
- PhoneVerifyForm component
- Profile Hub page
- UI/UX improvements across all pages
- landing.js for homepage
- Config and routing updates
2026-02-16 00:51:39 +03:30

187 lines
10 KiB
C#

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;
// Updated imports to use CMS protobuf instead of FrontOffice.BFF
using CMSMicroservice.Protobuf.Protos.Category;
using CMSMicroservice.Protobuf.Protos.City;
using CMSMicroservice.Protobuf.Protos.Package;
using CMSMicroservice.Protobuf.Protos.Products;
using CMSMicroservice.Protobuf.Protos.Transactions;
using CMSMicroservice.Protobuf.Protos.User;
using CMSMicroservice.Protobuf.Protos.UserCarts;
using CMSMicroservice.Protobuf.Protos.UserOrder;
using CMSMicroservice.Protobuf.Protos.UserWallet;
using CMSMicroservice.Protobuf.Protos.UserWalletChangeLog;
using CMSMicroservice.Protobuf.Protos.UserAddress;
using CMSMicroservice.Protobuf.Protos.Configuration;
using CMSMicroservice.Protobuf.Protos.NetworkMembership;
using CMSMicroservice.Protobuf.Protos.Commission;
using CMSMicroservice.Protobuf.Protos.AppVersion;
using CMSMicroservice.Protobuf.Protos.SitePage;
using CMSMicroservice.Protobuf.Protos.BlogPost;
using CMSMicroservice.Protobuf.Protos.BlogCategory;
using CMSMicroservice.Protobuf.Protos.DiscountProduct;
using CMSMicroservice.Protobuf.Protos.DiscountCategory;
using CMSMicroservice.Protobuf.Protos.DiscountShoppingCart;
using CMSMicroservice.Protobuf.Protos.DiscountOrder;
using FrontOffice.Main.Utilities;
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;
});
// Access HttpContext for User-Agent
services.AddHttpContextAccessor();
// Register custom services
services.AddSingleton<UserAuthInfo>();
services.AddScoped<AuthService>();
services.AddScoped<AuthDialogService>();
// Storefront services
services.AddScoped<CartService>();
services.AddScoped<ProductService>();
services.AddScoped<CategoryService>();
services.AddScoped<OrderService>();
services.AddScoped<WalletService>();
services.AddScoped<VATService>(); // Singleton برای cache روزانه
// Package service
services.AddScoped<PackageService>();
// New services for Club, Network, Commission
services.AddScoped<ClubMembershipService>();
services.AddScoped<ClubConfigurationService>();
services.AddScoped<NetworkMembershipService>();
services.AddScoped<CommissionService>();
// App Version Service for cache invalidation
services.AddScoped<AppVersionService>();
// Main Service for core functionality
services.AddScoped<MainService>();
// Site Page service for dynamic content (About, Contact)
services.AddScoped<SitePageService>();
// Blog Post service for landing page latest posts & blog pages
services.AddScoped<BlogPostService>();
// Blog Category service for blog sidebar filters
services.AddScoped<BlogCategoryService>();
// Discount Store services
services.AddScoped<DiscountProductService>();
services.AddScoped<DiscountCartService>();
services.AddScoped<DiscountOrderService>();
// Device detection: very light, dependency-free
services.AddTransient<IDeviceDetector, DeviceDetector>();
// PDF generation (Chromium only)
services.AddSingleton<FrontOffice.Main.Utilities.Pdf.IChromiumPdfService, FrontOffice.Main.Utilities.Pdf.ChromiumPdfService>();
// SignalR Token Notification Service
services.AddScoped<TokenNotificationService>();
return services;
}
public static IServiceCollection AddGrpcServices(this IServiceCollection services, IConfiguration configuration)
{
var baseUrl = configuration["GwUrl"];
// Register optimized HttpClient for gRPC
services.AddScoped(sp =>
{
var handler = new HttpClientHandler
{
MaxConnectionsPerServer = 10,
AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate
};
return new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, handler))
{
Timeout = TimeSpan.FromMinutes(10),
BaseAddress = new Uri(baseUrl)
};
});
// Register gRPC clients with authentication - Updated for CMS
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.Package.PackageContract.PackageContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.User.UserContract.UserContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.UserOrder.UserOrderContract.UserOrderContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.UserWallet.UserWalletContract.UserWalletContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.Category.CategoryContract.CategoryContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.Products.ProductsContract.ProductsContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.Transactions.TransactionsContract.TransactionsContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.UserCarts.UserCartsContract.UserCartsContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.City.CityContract.CityContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.UserAddress.UserAddressContract.UserAddressContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.UserWalletChangeLog.UserWalletChangeLogContract.UserWalletChangeLogContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.ClubMembership.ClubMembershipContract.ClubMembershipContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.OtpToken.OtpTokenContract.OtpTokenContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.Configuration.ConfigurationContract.ConfigurationContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.NetworkMembership.NetworkMembershipContract.NetworkMembershipContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.Commission.CommissionContract.CommissionContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.AppVersion.AppVersionContract.AppVersionContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.SitePage.SitePageContract.SitePageContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.BlogPost.BlogPostContract.BlogPostContractClient>);
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.BlogCategory.BlogCategoryContract.BlogCategoryContractClient>);
// Image Resolver Service
services.AddScoped(CreateAuthenticatedClient<CMSMicroservice.Protobuf.Protos.ImageResolver.ImageResolverContract.ImageResolverContractClient>);
services.AddScoped<ImageCacheService>();
// Discount Store gRPC clients
services.AddScoped(CreateAuthenticatedClient<DiscountProductContract.DiscountProductContractClient>);
services.AddScoped(CreateAuthenticatedClient<DiscountCategoryContract.DiscountCategoryContractClient>);
services.AddScoped(CreateAuthenticatedClient<DiscountShoppingCartContract.DiscountShoppingCartContractClient>);
services.AddScoped(CreateAuthenticatedClient<DiscountOrderContract.DiscountOrderContractClient>);
return services;
}
private static TClient CreateAuthenticatedClient<TClient>(IServiceProvider sp)
where TClient : class
{
var httpClient = sp.GetRequiredService<HttpClient>();
var localStorage = sp.GetRequiredService<ILocalStorageService>();
var baseUrl = httpClient.BaseAddress?.ToString() ?? throw new InvalidOperationException("Base URL not configured");
var credentials = CallCredentials.FromInterceptor(async (context, metadata) =>
{
try
{
var token = await localStorage.GetItemAsync<string>("auth:token");
if (!string.IsNullOrWhiteSpace(token))
{
metadata.Add("Authorization", $"Bearer {token}");
}
}
catch (Exception ex)
{
#if DEBUG
Console.WriteLine($"Token retrieval error: {ex.Message}");
#endif
}
});
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 (TClient)Activator.CreateInstance(typeof(TClient), channel)!;
}
}