diff --git a/WebDoorCreator.API/Data/ApiDataService.cs b/WebDoorCreator.API/Data/ApiDataService.cs new file mode 100644 index 0000000..8bcc5a9 --- /dev/null +++ b/WebDoorCreator.API/Data/ApiDataService.cs @@ -0,0 +1,253 @@ +using Microsoft.AspNetCore.Identity.UI.Services; +using Newtonsoft.Json; +using NLog; +using StackExchange.Redis; +using System.Diagnostics; +using WebDoorCreator.Core; +using WebDoorCreator.Data.DbModels; + +namespace WebDoorCreator.API.Data +{ + public class ApiDataService : IDisposable + { + #region Public Fields + + /// + /// Classe Accesso metodi DB + /// + public static WebDoorCreator.Data.Controllers.WebDoorCreatorController dbController = null!; + + #endregion Public Fields + + #region Public Constructors + + /// + /// Init classe + /// + /// + /// + /// + /// + public ApiDataService(IConfiguration configuration, IEmailSender emailSender, IConnectionMultiplexer redisConn) + { + _configuration = configuration; + _emailSender = emailSender; + // setup compoenti REDIS + var redConnString = _configuration.GetConnectionString("Redis"); + if (redConnString == null) + { + Log.Error("REDIS ConnString empty!"); + } + else + { + this.redisConn = ConnectionMultiplexer.Connect(redConnString); + this.redisDb = this.redisConn.GetDatabase(); + } + + // Conf DB + var connStrDB = _configuration.GetConnectionString("WDC.DB"); + if (string.IsNullOrEmpty(connStrDB)) + { + Log.Error("ConnString empty!"); + } + else + { + dbController = new WebDoorCreator.Data.Controllers.WebDoorCreatorController(configuration); + Log.Info("DbController OK"); + } + } + + #endregion Public Constructors + + #region Public Methods + + public void Dispose() + { + // Clear database controller + dbController.Dispose(); + } + + /// + /// Doors list by orderId + /// + public async Task?> DoorGetByOrderId(int orderId) + { + string source = "DB"; + List? dbResult = new List(); + // cerco da cache + string currKey = $"{Constants.rKeyOrderDetail}:{orderId}"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + string? rawData = await redisDb.StringGetAsync(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + var tempResult = JsonConvert.DeserializeObject>(rawData); + if (tempResult == null) + { + dbResult = new List(); + } + else + { + dbResult = tempResult; + } + } + else + { + dbResult = dbController.DoorsGetByOrderId(orderId); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); + } + if (dbResult == null) + { + dbResult = new List(); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"DoorGetByOrderId | {source} in: {ts.TotalMilliseconds} ms"); + return dbResult; + } + + #endregion Public Methods + + #region Protected Fields + + protected const string rKeyCalcOreFase = "Check:OreFasi"; + protected const string rKeyFasiAct = "Check:FasiAct"; + protected const string rKeyProjAct = "Check:ProjAct"; + + /// + /// TTL da 1 min x cache Redis + /// + protected const int shortTTL = 60 * 5; + + protected Random rnd = new Random(); + + #endregion Protected Fields + + #region Protected Methods + + /// + /// Recupero chiave da redis + /// + /// + /// + protected async Task getRSV(string rKey) + { + string answ = ""; + var rawData = await redisDb.StringGetAsync(rKey); + if (rawData.HasValue) + { + answ = $"{rawData}"; + } + return answ; + } + + /// + /// Salvataggio chiave in redis + /// + /// + /// + /// + /// + protected async Task setRSV(string rKey, string rVal, int ttlSec) + { + bool fatto = false; + await redisDb.StringSetAsync(rKey, rVal, TimeSpan.FromSeconds(ttlSec)); + fatto = true; + return fatto; + } + + /// + /// Salvataggio chiave in redis + /// + /// + /// + /// + /// + protected async Task setRSV(string rKey, int rValInt, int ttlSec) + { + bool fatto = false; + await redisDb.StringSetAsync(rKey, rValInt, TimeSpan.FromSeconds(ttlSec)); + fatto = true; + return fatto; + } + + /// + /// Registra in cache chiave se non fosse già in elenco + /// + /// + protected void trackCache(string newKey) + { + if (!cachedDataList.Contains(newKey)) + { + cachedDataList.Add(newKey); + } + } + + #endregion Protected Methods + + #region Private Fields + + private static IConfiguration _configuration = null!; + private static JsonSerializerSettings? JSSettings; + private static Logger Log = LogManager.GetCurrentClassLogger(); + + private readonly IEmailSender _emailSender; + + /// + /// Elenco obj in cache + /// + private List cachedDataList = new List(); + + /// + /// Durata cache lunga IN SECONDI + /// + private int cacheTtlLong = 60 * 5; + + /// + /// Durata cache breve IN SECONDI + /// + private int cacheTtlShort = 60 * 1; + + /// + /// Oggetto per connessione a REDIS + /// + private ConnectionMultiplexer redisConn = null!; + + /// + /// Oggetto DB redis da impiegare x chiamate R/W + /// + private IDatabase redisDb = null!; + + #endregion Private Fields + + #region Private Properties + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan FastCache + { + get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000); + } + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan LongCache + { + get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000); + } + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan UltraLongCache + { + get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000); + } + + #endregion Private Properties + } +} \ No newline at end of file diff --git a/WebDoorCreator.API/NLog.config b/WebDoorCreator.API/NLog.config new file mode 100644 index 0000000..bd41408 --- /dev/null +++ b/WebDoorCreator.API/NLog.config @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WebDoorCreator.API/Program.cs b/WebDoorCreator.API/Program.cs index a78947f..56cf12e 100644 --- a/WebDoorCreator.API/Program.cs +++ b/WebDoorCreator.API/Program.cs @@ -1,14 +1,63 @@ +using Microsoft.AspNetCore.Identity.UI.Services; +using Microsoft.AspNetCore.Localization; +using StackExchange.Redis; +using StackExchange.Redis.Extensions.Core.Configuration; +using StackExchange.Redis.Extensions.Newtonsoft; +using System.Globalization; +using System.Text.Json.Serialization; +using WebDoorCreator.API.Data; +using WebDoorCreator.Data; + var builder = WebApplication.CreateBuilder(args); -// Add services to the container. + +// configuration setup +ConfigurationManager configuration = builder.Configuration; +// Redis +var connStringRedis = configuration.GetConnectionString("Redis"); +string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); + +// avvio oggetto shared x redis... +var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + +// Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); -// aggiunta servizi x accesso dati... +// abilitazione x email management con MailKit +//builder.Services.AddTransient(); +builder.Services.AddSingleton(); +builder.Services.Configure(options => +{ + options.Host_Address = configuration["ExternalProviders:MailKit:SMTP:Address"] ?? ""; + options.Host_Port = Convert.ToInt32(configuration["ExternalProviders:MailKit:SMTP:Port"] ?? ""); + options.Host_Username = configuration["ExternalProviders:MailKit:SMTP:Account"] ?? ""; + options.Host_Password = configuration["ExternalProviders:MailKit:SMTP:Password"] ?? ""; + options.Sender_EMail = configuration["ExternalProviders:MailKit:SMTP:SenderEmail"] ?? ""; + options.Sender_Name = configuration["ExternalProviders:MailKit:SMTP:SenderName"] ?? ""; +}); +// aggiunta servizi x accesso dati... +builder.Services.AddControllers() + .AddJsonOptions(c => c.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve); + +builder.Services.AddStackExchangeRedisExtensions((options) => +{ + List newConf = new List(); + var currConf = configuration.GetSection("Redis").Get(); + if (currConf != null) + { + newConf.Add(currConf); + } + return newConf; + //return configuration.GetSection("Redis").Get(); +}); + +builder.Services.AddSingleton(); +builder.Services.AddSingleton(redisMultiplexer); var app = builder.Build(); @@ -21,6 +70,20 @@ if (app.Environment.IsDevelopment() || app.Environment.IsStaging()) app.UseSwaggerUI(); } + +//// cultura IT... +//var supportedCultures = new[]{ +// new CultureInfo("it-IT") +// }; +//app.UseRequestLocalization(new RequestLocalizationOptions +//{ +// DefaultRequestCulture = new RequestCulture("it-IT"), +// SupportedCultures = supportedCultures, +// FallBackToParentCultures = false +//}); +//CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT"); + + app.UseHttpsRedirection(); app.UseAuthorization(); diff --git a/WebDoorCreator.API/WebDoorCreator.API.csproj b/WebDoorCreator.API/WebDoorCreator.API.csproj index 0ab645d..3a61c6f 100644 --- a/WebDoorCreator.API/WebDoorCreator.API.csproj +++ b/WebDoorCreator.API/WebDoorCreator.API.csproj @@ -11,8 +11,18 @@ + + + + + + + + + + diff --git a/WebDoorCreator.API/appsettings.json b/WebDoorCreator.API/appsettings.json index 10f68b8..c878c27 100644 --- a/WebDoorCreator.API/appsettings.json +++ b/WebDoorCreator.API/appsettings.json @@ -5,5 +5,26 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "ConnectionStrings": { + "Redis": "localhost:6379,DefaultDatabase=11,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", + "WDC.DB": "Server=SQL2016DEV;Database=WebDoorCreator; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=WebDoorCreator.UI;" + }, + "ExternalProviders": { + "MailKit": { + "SMTP": { + "Address": "smtp-mail.outlook.com", + "Port": "587", + "Account": "steamwarebot@outlook.it", + "Password": "siamoInViaNazionale93", + "SenderEmail": "steamwarebot@outlook.it", + "SenderName": "Steamware Email BOT" + } + } + }, + "MailDest": { + "Admin": "samuele@steamware.net", + "ProjCheck": "samuele.locatelli@egalware.com,mara.baroni@egalware.com", + "TimbCheck": "samuele.locatelli@egalware.com,mara.baroni@egalware.com" + } } diff --git a/WebDoorCreator.API/logs/.placeholder.txt b/WebDoorCreator.API/logs/.placeholder.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/WebDoorCreator.API/logs/.placeholder.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/WebDoorCreator.Core/Constants.cs b/WebDoorCreator.Core/Constants.cs index b4aa1dc..b684365 100644 --- a/WebDoorCreator.Core/Constants.cs +++ b/WebDoorCreator.Core/Constants.cs @@ -23,5 +23,24 @@ namespace WebDoorCreator.Core // REDIS Channels messaggi (verso UI) public static readonly string CALC_REQ_QUEUE = $"CalcRequest"; public static readonly string CALC_DONE_QUEUE = $"CalcCompleted"; + + + public const string passPhrase = "9eb4660f-8753-46bc-b23b-08759ba03fe9"; + + // classi utilità x cache REDIS dati DB + public const string redisBaseAddr = "WDC"; + public const string rKeyCompany = $"{redisBaseAddr}:Cache:Company"; + public const string rKeyDoor = $"{redisBaseAddr}:Cache:Door"; + public const string rKeyDoorOp = $"{redisBaseAddr}:Cache:DoorOp"; + public const string rKeyDoorOpType = $"{redisBaseAddr}:Cache:DoorOpType"; + public const string rKeyGraphicParameters = $"{redisBaseAddr}:Cache:GraphicParameters"; + public const string rKeyListValues = $"{redisBaseAddr}:Cache:ListValues"; + public const string rKeyOrderDetail = $"{redisBaseAddr}:Cache:OrderDetail"; + public const string rKeyOrderStatus = $"{redisBaseAddr}:Cache:OrderStatus"; + public const string rKeyRoles = $"{redisBaseAddr}:Cache:Roles"; + public const string rKeyUsers = $"{redisBaseAddr}:Cache:Users"; + public const string rKeyUsersView = $"{redisBaseAddr}:Cache:UsersView"; + public const string rKeyVocLemma = $"{redisBaseAddr}:Cache:VocLemma"; + public const string rKeyLanguage = $"{redisBaseAddr}:Cache:Languages"; } } diff --git a/WebDoorCreator.UI/Data/WebDoorCreatorService.cs b/WebDoorCreator.UI/Data/WebDoorCreatorService.cs index 2599bff..d8e8add 100644 --- a/WebDoorCreator.UI/Data/WebDoorCreatorService.cs +++ b/WebDoorCreator.UI/Data/WebDoorCreatorService.cs @@ -74,7 +74,7 @@ namespace WebDoorCreator.UI.Data { var dbResult = await dbController.CompanyAddMod(currRec); // elimino cache redis... - RedisValue pattern = new RedisValue($"{rKeyCompany}"); + RedisValue pattern = new RedisValue($"{Constants.rKeyCompany}"); bool answ = await ExecFlushRedisPattern(pattern); await Task.Delay(1); return dbResult; @@ -91,7 +91,7 @@ namespace WebDoorCreator.UI.Data List dbResult = new List(); // cerco da cache - string currKey = $"{rKeyCompany}:{id}"; + string currKey = $"{Constants.rKeyCompany}:{id}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -433,7 +433,7 @@ namespace WebDoorCreator.UI.Data public string DecriptData(string encData) { - return SteamCrypto.DecryptString(encData, passPhrase); + return SteamCrypto.DecryptString(encData, Constants.passPhrase); } /// @@ -462,10 +462,10 @@ namespace WebDoorCreator.UI.Data /// public async Task DoorFlushCache(int DoorId) { - RedisValue pattern = new RedisValue($"{rKeyDoor}:*"); + RedisValue pattern = new RedisValue($"{Constants.rKeyDoor}:*"); if (DoorId > 0) { - pattern = new RedisValue($"{rKeyDoor}:{DoorId}:*"); + pattern = new RedisValue($"{Constants.rKeyDoor}:{DoorId}:*"); } bool answ = await ExecFlushRedisPattern(pattern); return answ; @@ -479,7 +479,7 @@ namespace WebDoorCreator.UI.Data string source = "DB"; List? dbResult = new List(); // cerco da cache - string currKey = $"{rKeyOrderDetail}:{orderId}"; + string currKey = $"{Constants.rKeyOrderDetail}:{orderId}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -550,10 +550,10 @@ namespace WebDoorCreator.UI.Data /// public async Task DoorOpFlushCache(int DoorId) { - RedisValue pattern = new RedisValue($"{rKeyDoorOp}*"); + RedisValue pattern = new RedisValue($"{Constants.rKeyDoorOp}*"); if (DoorId > 0) { - pattern = new RedisValue($"{rKeyDoorOp}:{DoorId}*"); + pattern = new RedisValue($"{Constants.rKeyDoorOp}:{DoorId}*"); } bool answ = await ExecFlushRedisPattern(pattern); return answ; @@ -567,7 +567,7 @@ namespace WebDoorCreator.UI.Data string source = "DB"; List? dbResult = new List(); // cerco da cache - string currKey = $"{rKeyDoorOp}:{doorId}"; + string currKey = $"{Constants.rKeyDoorOp}:{doorId}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -607,7 +607,7 @@ namespace WebDoorCreator.UI.Data // cerco da cache Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - string currKey = $"{rKeyVocLemma}"; + string currKey = $"{Constants.rKeyVocLemma}"; string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { @@ -723,7 +723,7 @@ namespace WebDoorCreator.UI.Data string source = "DB"; List? dbResult = new List(); // cerco da cache - string currKey = $"{rKeyDoorOpType}"; + string currKey = $"{Constants.rKeyDoorOpType}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); #if false @@ -767,7 +767,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); string source = "DB"; // cerco da cache - string currKey = $"{rKeyDoorOpType}:DEFAULT"; + string currKey = $"{Constants.rKeyDoorOpType}:DEFAULT"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); #if false @@ -887,13 +887,13 @@ namespace WebDoorCreator.UI.Data public string EncriptData(string rawData) { - return SteamCrypto.EncryptString(rawData, passPhrase); + return SteamCrypto.EncryptString(rawData, Constants.passPhrase); } public async Task FlushRedisCache() { await Task.Delay(1); - RedisValue pattern = new RedisValue($"{redisBaseAddr}*"); + RedisValue pattern = new RedisValue($"{Constants.redisBaseAddr}*"); bool answ = await ExecFlushRedisPattern(pattern); return answ; } @@ -975,7 +975,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); string currKey = ""; // cerco da cache - currKey = $"{rKeyListValues}:{tableName}:{fieldName}"; + currKey = $"{Constants.rKeyListValues}:{tableName}:{fieldName}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); @@ -1019,7 +1019,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); // cerco da cache - string currKey = $"{rKeyLanguage}"; + string currKey = $"{Constants.rKeyLanguage}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -1061,7 +1061,7 @@ namespace WebDoorCreator.UI.Data { var dbResult = await dbController.OrderAdd(currRec); // elimino cache redis... - RedisValue pattern = new RedisValue($"{rKeyOrderStatus}:*"); + RedisValue pattern = new RedisValue($"{Constants.rKeyOrderStatus}:*"); bool answ = await ExecFlushRedisPattern(pattern); return dbResult; } @@ -1073,10 +1073,10 @@ namespace WebDoorCreator.UI.Data /// public async Task OrderDetailFlushCache(int OrderId) { - RedisValue pattern = new RedisValue($"{rKeyOrderDetail}:*"); + RedisValue pattern = new RedisValue($"{Constants.rKeyOrderDetail}:*"); if (OrderId > 0) { - pattern = new RedisValue($"{rKeyOrderDetail}:{OrderId}"); + pattern = new RedisValue($"{Constants.rKeyOrderDetail}:{OrderId}"); } bool answ = await ExecFlushRedisPattern(pattern); return answ; @@ -1091,7 +1091,7 @@ namespace WebDoorCreator.UI.Data { var dbResult = await dbController.OrderRem(OrdId); // elimino cache redis... - RedisValue pattern = new RedisValue($"{rKeyOrderStatus}:*"); + RedisValue pattern = new RedisValue($"{Constants.rKeyOrderStatus}:*"); bool answ = await ExecFlushRedisPattern(pattern); return dbResult; } @@ -1103,7 +1103,7 @@ namespace WebDoorCreator.UI.Data /// public async Task OrdersFlushCache() { - RedisValue pattern = new RedisValue($"{rKeyOrderStatus}:*"); + RedisValue pattern = new RedisValue($"{Constants.rKeyOrderStatus}:*"); bool answ = await ExecFlushRedisPattern(pattern); return answ; } @@ -1114,7 +1114,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); // cerco da cache - string currKey = $"{rKeyOrderStatus}:{companyId}:{orderStatus}:{dataFrom:yyyyMMdd}:{dataTo:yyyyMMdd}"; + string currKey = $"{Constants.rKeyOrderStatus}:{companyId}:{orderStatus}:{dataFrom:yyyyMMdd}:{dataTo:yyyyMMdd}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -1156,7 +1156,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); // cerco da cache - string currKey = $"{rKeyGraphicParameters}:{hwId}"; + string currKey = $"{Constants.rKeyGraphicParameters}:{hwId}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -1198,7 +1198,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); // cerco da cache - string currKey = rKeyRoles; + string currKey = Constants.rKeyRoles; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -1240,7 +1240,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); // cerco da cache - string currKey = rKeyUsers; + string currKey = Constants.rKeyUsers; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -1282,7 +1282,7 @@ namespace WebDoorCreator.UI.Data AspNetUsers dbResult = new AspNetUsers(); // cerco da cache - string currKey = $"{rKeyUsers}:{userId}"; + string currKey = $"{Constants.rKeyUsers}:{userId}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -1324,7 +1324,7 @@ namespace WebDoorCreator.UI.Data List? dbResult = new List(); // cerco da cache - string currKey = rKeyUsersView; + string currKey = Constants.rKeyUsersView; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); @@ -1361,35 +1361,6 @@ namespace WebDoorCreator.UI.Data #region Protected Fields - protected const string passPhrase = "9eb4660f-8753-46bc-b23b-08759ba03fe9"; - - protected const string redisBaseAddr = "WDC"; - - protected const string rKeyCompany = $"{redisBaseAddr}:Cache:Company"; - - protected const string rKeyDoor = $"{redisBaseAddr}:Cache:Door"; - - protected const string rKeyDoorOp = $"{redisBaseAddr}:Cache:DoorOp"; - - protected const string rKeyDoorOpType = $"{redisBaseAddr}:Cache:DoorOpType"; - - protected const string rKeyGraphicParameters = $"{redisBaseAddr}:Cache:GraphicParameters"; - - protected const string rKeyListValues = $"{redisBaseAddr}:Cache:ListValues"; - - protected const string rKeyOrderDetail = $"{redisBaseAddr}:Cache:OrderDetail"; - - protected const string rKeyOrderStatus = $"{redisBaseAddr}:Cache:OrderStatus"; - - protected const string rKeyRoles = $"{redisBaseAddr}:Cache:Roles"; - - protected const string rKeyUsers = $"{redisBaseAddr}:Cache:Users"; - - protected const string rKeyUsersView = $"{redisBaseAddr}:Cache:UsersView"; - - protected const string rKeyVocLemma = $"{redisBaseAddr}:Cache:VocLemma"; - - protected const string rKeyLanguage = $"{redisBaseAddr}:Cache:Languages"; protected Random rnd = new Random();