using Microsoft.AspNetCore.Identity.UI.Services; using Newtonsoft.Json; using NLog; using StackExchange.Redis; using System.Diagnostics; using WebDoorCreator.Data.Controllers; namespace WebDoorCreator.UI.Data { public class WDCVocabularyService { #region Public Fields public static WebDoorCreatorController dbController = null!; #endregion Public Fields #region Public Constructors public WDCVocabularyService(IConfiguration configuration, IConnectionMultiplexer redisConnMult, IEmailSender emailSender) { Log.Info("WDCVocabularyService starting..."); _configuration = configuration; _emailSender = emailSender; // Conf cache redisConn = redisConnMult; redisDb = this.redisConn.GetDatabase(); // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ JSSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; // cod app CodApp = _configuration["CodApp"]; // Conf DB string connStr = _configuration.GetConnectionString("WDC.DB"); if (string.IsNullOrEmpty(connStr)) { Log.Info("ConnString empty!"); } else { dbController = new WebDoorCreatorController(configuration); } if (dbController != null) { if (VocabularyLemmas == null) { VocabularyLemmas = Task.Run(async () => await VocLemmaGetAll()).Result; } } Log.Info("WDCVocabularyService started!"); } #endregion Public Constructors #region Public Properties public string CodApp { get; set; } = ""; public Dictionary>? VocabularyLemmas { get => _vocabularyLemmas; set { if (_vocabularyLemmas != value) { _vocabularyLemmas = value; } } } #endregion Public Properties #region Public Methods /// /// Forza reload vocabolario /// /// public async Task ReloadVoc() { VocabularyLemmas = await VocLemmaGetAll(); } public string Traduci(string lingua, string lemma) { string answ = lemma; if (VocabularyLemmas != null && VocabularyLemmas.ContainsKey(lingua)) { if (VocabularyLemmas[lingua].ContainsKey(lemma)) { answ = VocabularyLemmas[lingua][lemma]; } } return answ; } public async Task>?> VocLemmaGetAll() { string source = "DB"; Dictionary>? dbResult = new Dictionary>(); // cerco da cache Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string currKey = $"{rKeyVocLemma}"; string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>>(rawData); if (tempResult == null) { dbResult = new Dictionary>(); } else { dbResult = tempResult; } } else { dbResult = dbController.VocLemmaGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new Dictionary>(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"VocLemmaGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } #endregion Public Methods #region Protected Fields protected const string redisBaseAddr = "WDC"; protected const string rKeyVocLemma = $"{redisBaseAddr}:Cache:VocLemma"; protected Random rnd = new Random(); #endregion Protected Fields #region Private Fields private static IConfiguration _configuration = null!; private static JsonSerializerSettings? JSSettings; private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IEmailSender _emailSender; /// /// Durata cache lunga IN SECONDI /// private int cacheTtlLong = 60 * 5; /// /// Oggetto per connessione a REDIS /// private IConnectionMultiplexer redisConn; /// /// Oggetto DB redis da impiegare x chiamate R/W /// private IDatabase redisDb = null!; #endregion Private Fields #region Private Properties private Dictionary>? _vocabularyLemmas { get; set; } = null; private TimeSpan UltraLongCache { get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000); } #endregion Private Properties } }