diff --git a/RhSolutions.AddIn/AddIn/RhSolutionsFunctions.cs b/RhSolutions.AddIn/AddIn/RhSolutionsFunctions.cs index 4341ddf..88edc88 100644 --- a/RhSolutions.AddIn/AddIn/RhSolutionsFunctions.cs +++ b/RhSolutions.AddIn/AddIn/RhSolutionsFunctions.cs @@ -2,6 +2,8 @@ using System.Runtime.Versioning; #endif +using Microsoft.Extensions.Caching.Memory; + namespace RhSolutions.AddIn; #if !NET472 @@ -190,29 +192,33 @@ public class RhSolutionsFunctions public static object КУРСЕВРО([ExcelArgument(Name = "ДАТА", Description = "Дата в формате Excel (необязательно)")] double dateField) { ICurrencyClient currencyClient = RhSolutionsAddIn.ServiceProvider.GetRequiredService(); + IMemoryCache memoryCache = RhSolutionsAddIn.ServiceProvider.GetRequiredService(); + DateTime date = dateField == 0 ? DateTime.Today : DateTime.FromOADate(dateField); - if (ExcelAsyncUtil.Run(nameof(КУРСЕВРО), dateField, delegate + if (!memoryCache.TryGetValue(date, out decimal exchangeRate)) { - DateTime date = dateField == 0 ? DateTime.Today : DateTime.FromOADate(dateField); - var exchangeRate = currencyClient.GetCurrencyCourse(date) - .GetAwaiter() - .GetResult(); - - return exchangeRate ?? -1m; - }) is not decimal requestResult) - { - return "Загрузка..."; - } - else - { - if (requestResult < 0) + var result = ExcelAsyncUtil.Run(nameof(КУРСЕВРО), dateField, delegate { - return ExcelError.ExcelErrorNA; + var requestResult = currencyClient.GetCurrencyCourse(date) + .GetAwaiter() + .GetResult(); + + return requestResult ?? -1m; + }); + + if (result is not decimal) + { + return "Загрузка..."; } else { - return Math.Round(requestResult, 2); + exchangeRate = (decimal)result; + var cacheEntryOptions = new MemoryCacheEntryOptions() + .SetSlidingExpiration(TimeSpan.FromHours(1)); + memoryCache.Set(date, exchangeRate, cacheEntryOptions); } } + + return exchangeRate < 0 ? ExcelError.ExcelErrorNA : exchangeRate; } } \ No newline at end of file diff --git a/RhSolutions.AddIn/Services/CurrencyClient.cs b/RhSolutions.AddIn/Services/CurrencyClient.cs index fcc48ea..9601ffb 100644 --- a/RhSolutions.AddIn/Services/CurrencyClient.cs +++ b/RhSolutions.AddIn/Services/CurrencyClient.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.Caching.Memory; -using System.Net; +using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Xml.Linq; @@ -9,43 +8,34 @@ namespace RhSolutions.Services; public class CurrencyClient : ICurrencyClient { private readonly HttpClient _httpClient; - private readonly IMemoryCache _memoryCache; - private const string requestAddress = @"https://www.cbr.ru/scripts/XML_daily.asp?date_req="; + private const string _requestAddress = @"https://www.cbr.ru/scripts/XML_daily.asp?date_req="; public HttpStatusCode StatusCode { get; private set; } - public CurrencyClient(HttpClient httpClient, IMemoryCache memoryCache) + public CurrencyClient(HttpClient httpClient) { _httpClient = httpClient; - _memoryCache = memoryCache; } public async Task GetCurrencyCourse(DateTime date) { - if (!_memoryCache.TryGetValue(date, out decimal? exchangeRate)) + string request = $"{_requestAddress}{date.Date:dd/MM/yyyy}"; + HttpResponseMessage response = await _httpClient.GetAsync(request); + try { - string request = $"{requestAddress}{date.Date:dd/MM/yyyy}"; - HttpResponseMessage response = await _httpClient.GetAsync(request); - try - { - response.EnsureSuccessStatusCode(); - string xml = await response.Content.ReadAsStringAsync(); - XElement valCourses = XElement.Parse(xml); - exchangeRate = decimal.Parse(valCourses.Elements("Valute") - .Where(e => e.Element("Name").Value == "Евро") - .FirstOrDefault() - .Element("Value").Value); - return exchangeRate; - } - catch - { - StatusCode = response.StatusCode; - exchangeRate = null; - } + response.EnsureSuccessStatusCode(); + string xml = await response.Content.ReadAsStringAsync(); + XElement valCourses = XElement.Parse(xml); - var cacheEntryOptions = new MemoryCacheEntryOptions() - .SetSlidingExpiration(TimeSpan.FromHours(1)); - _memoryCache.Set(date, exchangeRate, cacheEntryOptions); + decimal? exchangeRate = decimal.Parse(valCourses.Elements("Valute") + .Where(e => e.Element("Name").Value == "Евро") + .FirstOrDefault() + .Element("Value").Value); + return exchangeRate; + } + catch + { + StatusCode = response.StatusCode; + return null; } - return exchangeRate; } } \ No newline at end of file