using System.Globalization; using System.Resources; namespace SharepointToolbox.Web.Localization; /// /// String lookup backed by Strings.resx / Strings.fr.resx. /// /// Registered as Scoped: in Blazor Server each circuit gets its own instance with its own /// explicit . The culture is stored as a field (not read from the /// ambient ) because the interactive circuit does /// NOT inherit the request/middleware culture, and ambient culture does not reliably flow /// across render batches and SPA navigations. An explicit per-circuit field is deterministic: /// set it once at circuit start and every page in that circuit renders in the same language. /// /// The static (used by the export services) has no explicit culture and /// falls back to the ambient culture. /// public class TranslationSource { public static readonly TranslationSource Instance = new(); // Construct the ResourceManager with the explicit manifest base name rather // than Strings.ResourceManager: the generated designer carries a stale base // name ("SharepointToolbox.Strings") from before the project was renamed to // *.Web, so its lookups throw MissingManifestResourceException. The embedded // resource is "SharepointToolbox.Web.Localization.Strings". private readonly ResourceManager _resourceManager = new ResourceManager("SharepointToolbox.Web.Localization.Strings", typeof(TranslationSource).Assembly); private CultureInfo? _culture; public TranslationSource() { } /// Explicit lookup culture. When unset, falls back to the ambient UI culture. public CultureInfo Culture { get => _culture ?? CultureInfo.CurrentUICulture; set => _culture = value; } public string this[string key] => _resourceManager.GetString(key, Culture) ?? $"[{key}]"; /// Sets this instance's culture from a language code ("fr" → French, else English/invariant). public void SetCulture(string lang) => Culture = Resolve(lang); /// "fr" → French; anything else → invariant (the base Strings.resx, i.e. English). public static CultureInfo Resolve(string lang) => lang switch { "fr" => new CultureInfo("fr"), _ => CultureInfo.InvariantCulture }; }