diff options
-rw-r--r-- | RhSolutions.AddIn/AddIn/RhSolutionsAddIn.cs | 1 | ||||
-rw-r--r-- | RhSolutions.AddIn/Properties/AssemblyInfo.cs | 4 | ||||
-rw-r--r-- | RhSolutions.AddIn/RhSolutions-AddIn.dna | 2 | ||||
-rw-r--r-- | RhSolutions.AddIn/RhSolutions.AddIn.csproj | 1 | ||||
-rw-r--r-- | RhSolutions.AddIn/Services/CurrencyClient.cs | 54 | ||||
-rw-r--r-- | RhSolutions.AddIn/Services/DatabaseClient.cs | 41 |
6 files changed, 63 insertions, 40 deletions
diff --git a/RhSolutions.AddIn/AddIn/RhSolutionsAddIn.cs b/RhSolutions.AddIn/AddIn/RhSolutionsAddIn.cs index bf9c992..2ddff1a 100644 --- a/RhSolutions.AddIn/AddIn/RhSolutionsAddIn.cs +++ b/RhSolutions.AddIn/AddIn/RhSolutionsAddIn.cs @@ -19,6 +19,7 @@ public sealed class RhSolutionsAddIn : IExcelAddIn IServiceCollection Services = new ServiceCollection(); Services.AddHttpClient() + .AddMemoryCache() .AddSingleton((Application)ExcelDnaUtil.Application) .AddSingleton<IAddInConfiguration, AddInConfiguration>() .AddSingleton<IDatabaseClient, DatabaseClient>() diff --git a/RhSolutions.AddIn/Properties/AssemblyInfo.cs b/RhSolutions.AddIn/Properties/AssemblyInfo.cs index fd55a65..9005468 100644 --- a/RhSolutions.AddIn/Properties/AssemblyInfo.cs +++ b/RhSolutions.AddIn/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.6.3.0")] -[assembly: AssemblyFileVersion("1.6.3.0")] +[assembly: AssemblyVersion("1.6.4.0")] +[assembly: AssemblyFileVersion("1.6.4.0")] diff --git a/RhSolutions.AddIn/RhSolutions-AddIn.dna b/RhSolutions.AddIn/RhSolutions-AddIn.dna index feb0454..32a6910 100644 --- a/RhSolutions.AddIn/RhSolutions-AddIn.dna +++ b/RhSolutions.AddIn/RhSolutions-AddIn.dna @@ -3,6 +3,8 @@ <ExternalLibrary Path="RhSolutions.AddIn.dll" ExplicitExports="false" LoadFromBytes="true" Pack="true" IncludePdb="false" /> <Reference Path="Microsoft.Bcl.AsyncInterfaces.dll" Pack="true" /> <Reference Path="Microsoft.Bcl.HashCode.dll" Pack="true" /> + <Reference Path="Microsoft.Extensions.Caching.Abstractions.dll" Pack="true" /> + <Reference Path="Microsoft.Extensions.Caching.Memory.dll" Pack="true" /> <Reference Path="Microsoft.Extensions.DependencyInjection.Abstractions.dll" Pack="true" /> <Reference Path="Microsoft.Extensions.DependencyInjection.dll" Pack="true" /> <Reference Path="Microsoft.Extensions.Http.dll" Pack="true" /> diff --git a/RhSolutions.AddIn/RhSolutions.AddIn.csproj b/RhSolutions.AddIn/RhSolutions.AddIn.csproj index 34dc5f4..3bf1071 100644 --- a/RhSolutions.AddIn/RhSolutions.AddIn.csproj +++ b/RhSolutions.AddIn/RhSolutions.AddIn.csproj @@ -33,6 +33,7 @@ <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" /> <PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" /> <PackageReference Include="Microsoft.CSharp" Version="4.7.0" /> + <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" /> <PackageReference Include="netDxf" Version="2022.11.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> diff --git a/RhSolutions.AddIn/Services/CurrencyClient.cs b/RhSolutions.AddIn/Services/CurrencyClient.cs index 4f3b922..fcc48ea 100644 --- a/RhSolutions.AddIn/Services/CurrencyClient.cs +++ b/RhSolutions.AddIn/Services/CurrencyClient.cs @@ -1,4 +1,5 @@ -using System.Net; +using Microsoft.Extensions.Caching.Memory; +using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Xml.Linq; @@ -7,35 +8,44 @@ namespace RhSolutions.Services; public class CurrencyClient : ICurrencyClient { - private readonly HttpClient _httpClient; + private readonly HttpClient _httpClient; + private readonly IMemoryCache _memoryCache; + private const string requestAddress = @"https://www.cbr.ru/scripts/XML_daily.asp?date_req="; public HttpStatusCode StatusCode { get; private set; } - public CurrencyClient(IServiceProvider serviceProvider) + public CurrencyClient(HttpClient httpClient, IMemoryCache memoryCache) { - _httpClient = serviceProvider.GetRequiredService<HttpClient>(); + _httpClient = httpClient; + _memoryCache = memoryCache; } public async Task<decimal?> GetCurrencyCourse(DateTime date) { - string request = $"https://www.cbr.ru/scripts/XML_daily.asp?date_req={date.Date.ToString("dd/MM/yyyy")}"; - var response = await _httpClient.GetAsync(request); - - try - { - response.EnsureSuccessStatusCode(); - string xml = await response.Content.ReadAsStringAsync(); - XElement valCourses = XElement.Parse(xml); - var course = decimal.Parse(valCourses.Elements("Valute") - .Where(e => e.Element("Name").Value == "Евро") - .FirstOrDefault() - .Element("Value").Value); - return course; - } - catch + if (!_memoryCache.TryGetValue(date, out decimal? exchangeRate)) { - StatusCode = response.StatusCode; - } + 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; + } - return null; + var cacheEntryOptions = new MemoryCacheEntryOptions() + .SetSlidingExpiration(TimeSpan.FromHours(1)); + _memoryCache.Set(date, exchangeRate, cacheEntryOptions); + } + return exchangeRate; } }
\ No newline at end of file diff --git a/RhSolutions.AddIn/Services/DatabaseClient.cs b/RhSolutions.AddIn/Services/DatabaseClient.cs index ac3aff9..efcf607 100644 --- a/RhSolutions.AddIn/Services/DatabaseClient.cs +++ b/RhSolutions.AddIn/Services/DatabaseClient.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Microsoft.Extensions.Caching.Memory; +using Newtonsoft.Json; using System.Net; using System.Net.Http; using System.Threading.Tasks; @@ -7,12 +8,14 @@ namespace RhSolutions.Services; public class DatabaseClient : IDatabaseClient { - private readonly IServiceProvider serviceProvider; + private readonly HttpClient _httpClient; + private readonly IMemoryCache _memoryCache; public HttpStatusCode StatusCode { get; private set; } - public DatabaseClient(IServiceProvider provider) + public DatabaseClient(HttpClient httpClient, IMemoryCache memoryCache) { - this.serviceProvider = provider; + _httpClient = httpClient; + _memoryCache = memoryCache; } public async Task<IEnumerable<Product>> GetProducts(string line) @@ -29,20 +32,26 @@ public class DatabaseClient : IDatabaseClient request = @"https://rh.cebotari.ru/api/search?query=" + line; } - var client = serviceProvider.GetRequiredService<HttpClient>(); - var response = await client.GetAsync(request); - - try - { - response.EnsureSuccessStatusCode(); - string json = await response.Content.ReadAsStringAsync(); - return JsonConvert.DeserializeObject<IEnumerable<Product>>(json) ?? Enumerable.Empty<Product>(); - } - catch + if (!_memoryCache.TryGetValue(line, out IEnumerable<Product> products)) { - StatusCode = response.StatusCode; + var response = await _httpClient.GetAsync(request); + + try + { + response.EnsureSuccessStatusCode(); + string json = await response.Content.ReadAsStringAsync(); + products = JsonConvert.DeserializeObject<IEnumerable<Product>>(json) ?? Enumerable.Empty<Product>(); + } + catch + { + StatusCode = response.StatusCode; + } + + var cacheEntryOptions = new MemoryCacheEntryOptions() + .SetSlidingExpiration(TimeSpan.FromHours(1)); + _memoryCache.Set(line, products, cacheEntryOptions); } - return Enumerable.Empty<Product>(); + return products; } }
\ No newline at end of file |