Files
EnvelopeGenerator/EnvelopeGenerator.ReceiverUI/Program.cs
TekH 6fe99d0cd0 docs: add culture management migration warnings for Server/Auto
Prepare for Blazor Server/Auto migration by documenting current
WASM-specific culture initialization approach and providing
detailed migration checklist in COPILOT_CONTEXT.md.
2026-06-18 12:50:45 +02:00

79 lines
4.0 KiB
C#

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>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.Configure<ApiOptions>(opts =>
builder.Configuration.GetSection(ApiOptions.SectionName).Bind(opts));
builder.Services.Configure<PdfViewerOptions>(opts =>
builder.Configuration.GetSection(PdfViewerOptions.SectionName).Bind(opts));
builder.Services.AddScoped<DocumentService>();
builder.Services.AddScoped<AuthService>();
builder.Services.AddScoped<AnnotationService>();
builder.Services.AddScoped<EnvelopeReceiverService>();
builder.Services.AddScoped<DocReceiverElementService>();
builder.Services.AddScoped<SignatureCacheService>();
builder.Services.AddSingleton<AppVersionService>();
builder.Services.AddScoped<EnvelopeService>();
builder.Services.AddScoped<CultureService>();
// Localization services
builder.Services.AddLocalization();
builder.Services.AddDevExpressWebAssemblyBlazorReportViewer();
builder.Services.AddDevExpressWebAssemblyBlazorPdfViewer();
builder.Services.AddDevExpressBlazorReportingWebAssembly(configure => {
configure.UseDevelopmentMode();
});
builder.Services.AddScoped<IDataSourceWizardJsonConnectionStorage, CustomDataSourceWizardJsonDataConnectionStorage>();
builder.Services.AddScoped<IJsonDataConnectionProviderFactory, CustomJsonDataConnectionProviderFactory>();
builder.Services.AddScoped<IObjectDataSourceWizardTypeProvider, ObjectDataSourceWizardCustomTypeProvider>();
DevExpress.Utils.DeserializationSettings.RegisterTrustedClass(typeof(EnvelopeGenerator.ReceiverUI.Data.DataItemList));
DevExpress.Utils.DeserializationSettings.RegisterTrustedClass(typeof(EnvelopeGenerator.ReceiverUI.PredefinedReports.Report));
builder.Services.AddSingleton<InMemoryReportStorageWebExtension>();
builder.Services.AddSingleton<ReportStorageWebExtension>(sp => sp.GetRequiredService<InMemoryReportStorageWebExtension>());
builder.Services.AddScoped<IReportProviderAsync, CustomReportProvider>();
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<CultureService>();
var culture = await cultureService.InitializeCultureAsync();
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await FontLoader.LoadFonts(host.Services.GetRequiredService<HttpClient>(), new List<string> { "opensans.ttf" });
await host.RunAsync();