using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.Web; using EnvelopeGenerator.ReceiverUI; using DevExpress.DataAccess.Web; using EnvelopeGenerator.ReceiverUI.Services; using EnvelopeGenerator.ReceiverUI.Options; using DevExpress.XtraReports.Services; using DevExpress.Blazor.Reporting; using DevExpress.XtraReports.Web.Extensions; using EnvelopeGenerator.Application.Resources; using Microsoft.Extensions.Localization; using System.Globalization; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.Configure(opts => builder.Configuration.GetSection(ApiOptions.SectionName).Bind(opts)); builder.Services.Configure(opts => builder.Configuration.GetSection(PdfViewerOptions.SectionName).Bind(opts)); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); // Localization services builder.Services.AddLocalization(); builder.Services.AddDevExpressWebAssemblyBlazorReportViewer(); builder.Services.AddDevExpressWebAssemblyBlazorPdfViewer(); builder.Services.AddDevExpressBlazorReportingWebAssembly(configure => { configure.UseDevelopmentMode(); }); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); DevExpress.Utils.DeserializationSettings.RegisterTrustedClass(typeof(EnvelopeGenerator.ReceiverUI.Data.DataItemList)); DevExpress.Utils.DeserializationSettings.RegisterTrustedClass(typeof(EnvelopeGenerator.ReceiverUI.PredefinedReports.Report)); builder.Services.AddSingleton(); builder.Services.AddSingleton(sp => sp.GetRequiredService()); builder.Services.AddScoped(); ReportStorageWebExtension.RegisterExtensionGlobal(new InMemoryReportStorageWebExtension()); var host = builder.Build(); // ⚠️ IMPORTANT: BLAZOR WASM-SPECIFIC CULTURE INITIALIZATION // This approach sets DefaultThreadCurrentCulture globally, which is SAFE for WebAssembly // because each user runs their own isolated app instance in their browser. // // ⚠️ TODO: REMOVE/REFACTOR WHEN MIGRATING TO BLAZOR SERVER/AUTO // In Server/Auto render modes, this is DANGEROUS because: // - Server runs a single shared instance for all users // - Setting global culture affects ALL connected users simultaneously // - Race conditions and culture conflicts will occur // // Migration Guide: // - Option 1: Use RequestLocalizationMiddleware for per-request culture // - Option 2: Use CascadingParameter with per-circuit culture state // - See: https://learn.microsoft.com/aspnet/core/blazor/globalization-localization // // Related files to update on migration: // - LanguageSelector.razor (remove manual culture setting) // - App.razor (may need CascadingValue for culture) // - Startup/Program.cs (add middleware) var cultureService = host.Services.GetRequiredService(); var culture = await cultureService.InitializeCultureAsync(); CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; await FontLoader.LoadFonts(host.Services.GetRequiredService(), new List { "opensans.ttf" }); await host.RunAsync();