using FluentValidation; using Microsoft.AspNetCore.Connections.Features; using Microsoft.Extensions.Logging; using System.Globalization; using System.Linq.Expressions; using System.Security.Claims; namespace zero.Localization; public class CultureResolver : ICultureResolver { /// public CultureInfo Current { get; protected set; } protected ILogger Logger { get; private set; } protected IMessageAggregator MessageAggregator { get; private set; } public CultureResolver(ILogger logger, IMessageAggregator messageAggregator) { Logger = logger; MessageAggregator = messageAggregator; } /// public Task Resolve(IZeroContext context) { if (!TryConvert(context.Options.Language, out CultureInfo culture)) { culture = CultureInfo.CurrentCulture; } Set(culture); return Task.FromResult(culture); } /// public bool TryConvert(string isoCode, out CultureInfo culture) { try { culture = CultureInfo.CreateSpecificCulture(isoCode.Replace('_', '-')); if (culture.ThreeLetterISOLanguageName.IsNullOrEmpty()) { throw new Exception("ThreeLetterISOLanguageName is empty"); } if (culture.ThreeLetterISOLanguageName == "ivl") { throw new Exception("Invariant language is not allowed"); } return true; } catch (Exception ex) { Logger.LogWarning(ex, "Could not create culture from Language code {code}", isoCode); culture = null; return false; } } /// public void Set(CultureInfo culture) { CultureInfo.CurrentCulture = culture; CultureInfo.CurrentUICulture = culture; ValidatorOptions.Global.LanguageManager.Culture = culture; Current = culture; MessageAggregator.Publish(new CultureChangeMessage() { Culture = culture }); } /// public void Subscribe(Expression> handle) { MessageAggregator.Subscribe(handle); } } public interface ICultureResolver { /// /// Current culture /// CultureInfo Current { get; } /// /// Resolves the current application from either the backoffice user (in case it is backoffice request) /// or the domain (in case it is frontend request). /// Task Resolve(IZeroContext context); /// /// Tries to convert an ISO code to a culture /// bool TryConvert(string isoCode, out CultureInfo culture); /// /// Set a new culture for this request /// void Set(CultureInfo culture); /// /// Subscribe to culture change /// void Subscribe(Expression> handle); }