diff --git a/BusinessLogicLayer.Abstraction/BusinessLogicLayer.Abstraction.csproj b/BusinessLogicLayer.Abstraction/BusinessLogicLayer.Abstraction.csproj
new file mode 100644
index 0000000..c34e107
--- /dev/null
+++ b/BusinessLogicLayer.Abstraction/BusinessLogicLayer.Abstraction.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netcoreapp2.2
+ Abstraction
+
+
+
+
+
+
+
diff --git a/BusinessLogicLayer.Abstraction/Interfaces/ICurrencyProvider.cs b/BusinessLogicLayer.Abstraction/Interfaces/ICurrencyProvider.cs
new file mode 100644
index 0000000..52d6cf3
--- /dev/null
+++ b/BusinessLogicLayer.Abstraction/Interfaces/ICurrencyProvider.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using DataAccessLayer.Models.Entities;
+
+namespace Abstraction.Interfaces
+{
+ public interface ICurrencyProvider
+ {
+ Task> GetExchangeRateAsync();
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Abstraction/Interfaces/IOfficialSource.cs b/BusinessLogicLayer.Abstraction/Interfaces/IOfficialSource.cs
new file mode 100644
index 0000000..a06a83e
--- /dev/null
+++ b/BusinessLogicLayer.Abstraction/Interfaces/IOfficialSource.cs
@@ -0,0 +1,6 @@
+namespace Abstraction.Interfaces
+{
+ public interface IOfficialSource : ICurrencyProvider
+ {
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Abstraction/Interfaces/IResponseClient.cs b/BusinessLogicLayer.Abstraction/Interfaces/IResponseClient.cs
new file mode 100644
index 0000000..133e25b
--- /dev/null
+++ b/BusinessLogicLayer.Abstraction/Interfaces/IResponseClient.cs
@@ -0,0 +1,10 @@
+using System.Threading.Tasks;
+using DataAccessLayer.Models.Entities;
+
+namespace Abstraction.Interfaces
+{
+ public interface IResponseClient
+ {
+ Task SendResponse(Updates updates);
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Abstraction/Interfaces/IUnofficialSource.cs b/BusinessLogicLayer.Abstraction/Interfaces/IUnofficialSource.cs
new file mode 100644
index 0000000..daa1b93
--- /dev/null
+++ b/BusinessLogicLayer.Abstraction/Interfaces/IUnofficialSource.cs
@@ -0,0 +1,6 @@
+namespace Abstraction.Interfaces
+{
+ public interface IUnofficialSource : ICurrencyProvider
+ {
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Implementation/BusinessLogicLayer.Implementation.csproj b/BusinessLogicLayer.Implementation/BusinessLogicLayer.Implementation.csproj
new file mode 100644
index 0000000..679045a
--- /dev/null
+++ b/BusinessLogicLayer.Implementation/BusinessLogicLayer.Implementation.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BusinessLogicLayer.Implementation/Services/CbrExchangeRateProvider.cs b/BusinessLogicLayer.Implementation/Services/CbrExchangeRateProvider.cs
new file mode 100644
index 0000000..8c05740
--- /dev/null
+++ b/BusinessLogicLayer.Implementation/Services/CbrExchangeRateProvider.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Abstraction.Interfaces;
+using AutoMapper;
+using BusinessLogicLayer.Objects.Dtos;
+using BusinessLogicLayer.Objects.Dtos.Cbr;
+using DataAccessLayer.Models.Entities;
+using Flurl.Http;
+using Microsoft.Extensions.Configuration;
+
+namespace BusinessLogicLayer.Implementation.Services
+{
+ public class CbrExchangeRateProvider : IOfficialSource
+ {
+ private readonly IMapper _mapper;
+
+ private readonly IConfiguration _configuration;
+
+ public CbrExchangeRateProvider(IMapper mapper, IConfiguration configuration)
+ {
+ _mapper = mapper;
+
+ _configuration = configuration;
+ }
+
+
+ public async Task> GetExchangeRateAsync()
+ {
+ CbrResponse cbrResponse = await _configuration["Config:LinqCbr"]
+ .GetJsonAsync();
+
+ Currency[] currencies =
+ {
+ cbrResponse.Currencies.EUR,
+ cbrResponse.Currencies.UAH,
+ cbrResponse.Currencies.USD
+ };
+//
+// return currencies.Select(currency => new CurrencyDataResponse
+// {
+// DataSource = SourceType.Official,
+// Date = cbrResponse.Date,
+// Code = currency.CharCode,
+// Name = currency.Name,
+// Value = currency.Value / currency.Nominal
+// })
+// .ToList();
+
+ return _mapper.Map>(currencies,
+ options => options.Items[CbrConstants.Date] = cbrResponse.Date);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Implementation/Services/CurrateCurrencyProviderService.cs b/BusinessLogicLayer.Implementation/Services/CurrateCurrencyProviderService.cs
new file mode 100644
index 0000000..56220bb
--- /dev/null
+++ b/BusinessLogicLayer.Implementation/Services/CurrateCurrencyProviderService.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Abstraction.Interfaces;
+using BusinessLogicLayer.Objects.Dtos.Currate;
+using DataAccessLayer.Models.Entities;
+using DataAccessLayer.Models.Enums;
+using Flurl.Http;
+using Microsoft.Extensions.Configuration;
+
+namespace BusinessLogicLayer.Implementation.Services
+{
+ public class CurrateCurrencyProviderService : IUnofficialSource
+ {
+ private readonly IConfiguration _configuration;
+
+ public CurrateCurrencyProviderService(IConfiguration configuration)
+ {
+ _configuration = configuration;
+ }
+
+ public async Task> GetExchangeRateAsync()
+ {
+ CurrateResponse currateResponse =
+ await _configuration["Config:LinqCurrate"]
+ .GetJsonAsync();
+
+ return new[]
+ {
+ new CurrencyExchangeRate
+ {
+ DataSource = SourceType.Exchange,
+
+ Code = "EUR",
+
+ Date = DateTime.UtcNow,
+
+ Name = "Евро",
+
+ Value = currateResponse.Data.EURRUB
+ },
+
+ new CurrencyExchangeRate
+ {
+ DataSource = SourceType.Exchange,
+
+ Code = "USD",
+
+ Date = DateTime.UtcNow,
+
+ Name = "Доллар США",
+
+ Value = currateResponse.Data.USDRUB
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Implementation/Services/VkResponseClientService.cs b/BusinessLogicLayer.Implementation/Services/VkResponseClientService.cs
new file mode 100644
index 0000000..a40dbe0
--- /dev/null
+++ b/BusinessLogicLayer.Implementation/Services/VkResponseClientService.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Abstraction.Interfaces;
+using BusinessLogicLayer.Objects.Dtos;
+using DataAccessLayer.Models.Entities;
+using Microsoft.Extensions.Configuration;
+using VkNet.Abstractions;
+using VkNet.Model;
+using VkNet.Model.RequestParams;
+using VkNet.Utils;
+
+namespace BusinessLogicLayer.Implementation.Services
+{
+ public class VkResponseClientService : IResponseClient
+ {
+ private readonly IConfiguration _configuration;
+
+ private readonly IVkApi _vkApi;
+
+ private readonly ICurrencyProvider _currencyProviderService;
+
+ public VkResponseClientService(IVkApi vkApi, IConfiguration configuration,
+ ICurrencyProvider currencyProviderService)
+ {
+ _vkApi = vkApi;
+ _configuration = configuration;
+ _currencyProviderService = currencyProviderService;
+ }
+
+ public async Task SendResponse(Updates updates)
+ {
+ if (updates == null)
+ {
+ return string.Empty;
+ }
+ // Проверяем, что находится в поле "type"
+
+ switch (updates.Type)
+ {
+ // Если это уведомление для подтверждения адреса
+ case VkMessagesTypes.Confirmation:
+ // Отправляем строку для подтверждения
+ return _configuration["Config:Confirmation"];
+
+ case VkMessagesTypes.MessageNew:
+ {
+ // Десериализация
+ var vkMessage = Message.FromJson(new VkResponse(updates.Object));
+
+ // Отправим в ответ полученный от пользователя текст
+ IEnumerable currencies = await _currencyProviderService
+ .GetExchangeRateAsync();
+
+ string responseMessage = currencies.Aggregate(string.Empty,
+ (previous, current) => previous + $"{current.Name}: {current.Value} ₽\n");
+
+ if (vkMessage.PeerId != null)
+ {
+ _vkApi.Messages.Send(new MessagesSendParams
+ {
+ RandomId = new DateTime().Millisecond,
+
+ PeerId = vkMessage.PeerId.Value,
+
+ Message = responseMessage
+ });
+ }
+
+ return responseMessage;
+ }
+ }
+
+ return string.Empty;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Objects/BusinessLogicLayer.Objects.csproj b/BusinessLogicLayer.Objects/BusinessLogicLayer.Objects.csproj
new file mode 100644
index 0000000..ef31712
--- /dev/null
+++ b/BusinessLogicLayer.Objects/BusinessLogicLayer.Objects.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
diff --git a/BusinessLogicLayer.Objects/Constants/CbrConstants.cs b/BusinessLogicLayer.Objects/Constants/CbrConstants.cs
new file mode 100644
index 0000000..fe3e787
--- /dev/null
+++ b/BusinessLogicLayer.Objects/Constants/CbrConstants.cs
@@ -0,0 +1,7 @@
+namespace BusinessLogicLayer.Objects.Dtos
+{
+ public class CbrConstants
+ {
+ public const string Date = "Date";
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Objects/Constants/VkMessagesTypes.cs b/BusinessLogicLayer.Objects/Constants/VkMessagesTypes.cs
new file mode 100644
index 0000000..7577b7f
--- /dev/null
+++ b/BusinessLogicLayer.Objects/Constants/VkMessagesTypes.cs
@@ -0,0 +1,9 @@
+namespace BusinessLogicLayer.Objects.Dtos
+{
+ public class VkMessagesTypes
+ {
+ public const string Confirmation = "confirmation";
+
+ public const string MessageNew = "message_new";
+ }
+}
\ No newline at end of file
diff --git a/ConsoleAppCourseValut/Valute.cs b/BusinessLogicLayer.Objects/Dtos/Cbr/CbrCurrencies.cs
similarity index 51%
rename from ConsoleAppCourseValut/Valute.cs
rename to BusinessLogicLayer.Objects/Dtos/Cbr/CbrCurrencies.cs
index 91d8e0d..53213fa 100644
--- a/ConsoleAppCourseValut/Valute.cs
+++ b/BusinessLogicLayer.Objects/Dtos/Cbr/CbrCurrencies.cs
@@ -1,10 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ConsoleAppCourseCurrency
+namespace BusinessLogicLayer.Objects.Dtos.Cbr
{
- public class Valute
+ public class CbrCurrencies
{
public Currency USD { get; set; }
@@ -12,4 +8,4 @@ public class Valute
public Currency EUR { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Objects/Dtos/Cbr/CbrResponse.cs b/BusinessLogicLayer.Objects/Dtos/Cbr/CbrResponse.cs
new file mode 100644
index 0000000..941e999
--- /dev/null
+++ b/BusinessLogicLayer.Objects/Dtos/Cbr/CbrResponse.cs
@@ -0,0 +1,18 @@
+using System;
+using Newtonsoft.Json;
+
+namespace BusinessLogicLayer.Objects.Dtos.Cbr
+{
+ public class CbrResponse
+ {
+ public DateTime Date { get; set; }
+
+ public DateTime PreviousDate { get; set; }
+
+ ///
+ /// Валюты
+ ///
+ [JsonProperty("Valute")]
+ public CbrCurrencies Currencies { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ConsoleAppCourseValut/Currency.cs b/BusinessLogicLayer.Objects/Dtos/Cbr/Currency.cs
similarity index 63%
rename from ConsoleAppCourseValut/Currency.cs
rename to BusinessLogicLayer.Objects/Dtos/Cbr/Currency.cs
index 077f478..bd7ace3 100644
--- a/ConsoleAppCourseValut/Currency.cs
+++ b/BusinessLogicLayer.Objects/Dtos/Cbr/Currency.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ConsoleAppCourseCurrency
+namespace BusinessLogicLayer.Objects.Dtos.Cbr
{
public class Currency
{
@@ -19,8 +15,5 @@ public class Currency
public double Value { get; set; }
public double Previous { get; set; }
-
- public override string ToString() => $"Курс {Name}: {Value / Nominal} ₽";
}
-
-}
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Objects/Dtos/Currate/CurrateResponse.cs b/BusinessLogicLayer.Objects/Dtos/Currate/CurrateResponse.cs
new file mode 100644
index 0000000..11f7383
--- /dev/null
+++ b/BusinessLogicLayer.Objects/Dtos/Currate/CurrateResponse.cs
@@ -0,0 +1,15 @@
+namespace BusinessLogicLayer.Objects.Dtos.Currate
+{
+ public class CurrateResponse
+ {
+ public Currencies Data { get; set; }
+// {
+// "status": "200",
+// "message": "rates",
+// "data": {
+// "EURRUB": "71.3846",
+// "USDRUB": "58.059"
+// }
+// }
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Objects/Dtos/Currate/Currencies.cs b/BusinessLogicLayer.Objects/Dtos/Currate/Currencies.cs
new file mode 100644
index 0000000..ac11305
--- /dev/null
+++ b/BusinessLogicLayer.Objects/Dtos/Currate/Currencies.cs
@@ -0,0 +1,9 @@
+namespace BusinessLogicLayer.Objects.Dtos.Currate
+{
+ public class Currencies
+ {
+ public double EURRUB { get; set; }
+
+ public double USDRUB { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Tests/BusinessLogicLayer.Tests.csproj b/BusinessLogicLayer.Tests/BusinessLogicLayer.Tests.csproj
new file mode 100644
index 0000000..e453a1d
--- /dev/null
+++ b/BusinessLogicLayer.Tests/BusinessLogicLayer.Tests.csproj
@@ -0,0 +1,20 @@
+
+
+
+ netcoreapp2.2
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BusinessLogicLayer.Tests/CbrExchangeRateProviderTests.cs b/BusinessLogicLayer.Tests/CbrExchangeRateProviderTests.cs
new file mode 100644
index 0000000..130f00b
--- /dev/null
+++ b/BusinessLogicLayer.Tests/CbrExchangeRateProviderTests.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Threading.Tasks;
+using AutoMapper;
+using BusinessLogicLayer.Implementation.Services;
+using BusinessLogicLayer.Objects.Dtos.Cbr;
+using DataAccessLayer.Models.Entities;
+using DataAccessLayer.Models.Enums;
+using DataAccessLayer.Models.MapperProfiles;
+using Flurl.Http.Testing;
+using Microsoft.Extensions.Configuration;
+using Moq;
+using Xunit;
+
+namespace BusinessLogicLayer.Tests
+{
+ public class CbrExchangeRateProviderTests : IDisposable
+ {
+ Mock iConfiguration = new Mock();
+
+ public void Dispose()
+ {
+ _httpTest?.Dispose();
+ }
+
+ IMapper mapper =
+ new Mapper(new MapperConfiguration(config => config.AddProfile(new ExchangeRateMappingProfile())));
+
+ private HttpTest _httpTest;
+
+ public CbrExchangeRateProviderTests()
+ {
+ _httpTest = new HttpTest();
+ }
+
+ [Fact]
+ public async Task GetAnswerAsync_cbr()
+ {
+ //Arrange
+
+// _httpTest.RespondWith("{ \"Date\": \"2019-08-14T11:30:00+03:00\",\n \"PreviousDate\": \"2019-08-13T11:30:00+03:00\",\n \"PreviousURL\": \"\\/\\/www.cbr-xml-daily.ru\\/archive\\/2019\\/08\\/13\\/daily_json.js\",\n \"Timestamp\": \"2019-08-13T23:00:00+03:00\",\n \"Valute\": {\n " +
+// "\"EUR\": {\n \"ID\": \"R01010\",\n \"NumCode\": \"036\",\n \"CharCode\": \"EUR\",\n \"Nominal\": 1,\n \"Name\": \"Австралийский доллар\",\n \"Value\": 44.3664,\n \"Previous\": 44.2756\n },\n " +
+// " \"UAH\": {\n \"ID\": \"R01020A\",\n \"NumCode\": \"944\",\n \"CharCode\": \"UAH\",\n \"Nominal\": 1,\n \"Name\": \"Азербайджанский манат\",\n \"Value\": 38.6688,\n \"Previous\": 38.5669\n },\n " +
+// " \"USD\": {\n \"ID\": \"R01035\",\n \"NumCode\": \"826\",\n \"CharCode\": \"USD\",\n \"Nominal\": 1,\n \"Name\": \"Фунт стерлингов Соединенного королевства\",\n \"Value\": 79.1091,\n \"Previous\": 78.9005\n }}}");
+//
+ iConfiguration.SetupGet(configuration => configuration[It.IsAny()])
+ .Returns("http://a.com");
+
+ _httpTest.RespondWithJson(new CbrResponse
+ {
+ Date = DateTime.MinValue,
+ PreviousDate = DateTime.MinValue.AddDays(1),
+ Currencies = new CbrCurrencies
+ {
+ EUR = new Currency
+ {
+ ID = "R01010",
+ NumCode = "036",
+ CharCode = "EUR",
+ Nominal = 1,
+ Name = "Австралийский доллар",
+ Value = 44.3664,
+ Previous = 44.2756
+ },
+ UAH = new Currency
+ {
+ ID = "R01020A",
+ NumCode = "944",
+ CharCode = "UAH",
+ Nominal = 1,
+ Name = "Азербайджанский манат",
+ Value = 38.6688,
+ Previous = 38.5669
+ },
+ USD = new Currency
+ {
+ ID = "R01035",
+ NumCode = "826",
+ CharCode = "USD",
+ Nominal = 1,
+ Name = "Фунт стерлингов Соединенного королевства",
+ Value = 79.1091,
+ Previous = 78.900
+ }
+ }
+ });
+
+ var cbrCurrencyProviderService = new CbrExchangeRateProvider(mapper, iConfiguration.Object);
+
+ CurrencyExchangeRate[] currencyExchangeRates =
+ {
+ new CurrencyExchangeRate
+ {
+ DataSource = SourceType.Official,
+ Code = "EUR",
+ Name = "Австралийский доллар",
+ Value = 44.3664,
+ Date = DateTime.MinValue
+ },
+ new CurrencyExchangeRate
+ {
+ DataSource = SourceType.Official,
+ Code = "UAH",
+ Name = "Азербайджанский манат",
+ Value = 38.6688,
+ Date = DateTime.MinValue
+ },
+ new CurrencyExchangeRate
+ {
+ DataSource = SourceType.Official,
+ Code = "USD",
+ Name = "Фунт стерлингов Соединенного королевства",
+ Value = 79.1091,
+ Date = DateTime.MinValue
+ }
+ };
+
+ //Act
+
+ var actualResult = await cbrCurrencyProviderService.GetExchangeRateAsync();
+
+ //Assert
+
+ Assert.Equal(currencyExchangeRates, actualResult, new JsonSerializedComparer());
+ }
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Tests/JsonSerializedComparer.cs b/BusinessLogicLayer.Tests/JsonSerializedComparer.cs
new file mode 100644
index 0000000..5ee3c67
--- /dev/null
+++ b/BusinessLogicLayer.Tests/JsonSerializedComparer.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace BusinessLogicLayer.Tests
+{
+ public class JsonSerializedComparer : IEqualityComparer
+ {
+ public bool Equals(T first, T second)
+ {
+ var serializeFirstObject = JsonConvert.SerializeObject(first);
+ var serializeSecondObject = JsonConvert.SerializeObject(second);
+
+ return serializeSecondObject == serializeFirstObject;
+ }
+
+ public int GetHashCode(T obj)
+ {
+ return JsonConvert.SerializeObject(obj).GetHashCode();
+ }
+ }
+}
\ No newline at end of file
diff --git a/BusinessLogicLayer.Tests/VkResponseClientServiceTests.cs b/BusinessLogicLayer.Tests/VkResponseClientServiceTests.cs
new file mode 100644
index 0000000..bdcf318
--- /dev/null
+++ b/BusinessLogicLayer.Tests/VkResponseClientServiceTests.cs
@@ -0,0 +1,117 @@
+using System.Threading.Tasks;
+using Abstraction.Interfaces;
+using BusinessLogicLayer.Implementation.Services;
+using DataAccessLayer.Models.Entities;
+using Microsoft.Extensions.Configuration;
+using Moq;
+using Newtonsoft.Json.Linq;
+using VkNet.Abstractions;
+using Xunit;
+
+namespace BusinessLogicLayer.Tests
+{
+ public class VkResponseClientServiceTests
+ {
+ Mock iVkApi = new Mock();
+ Mock iConfiguration = new Mock();
+ Mock iCurrencyProvider = new Mock();
+
+ [Fact]
+ public async Task SendMessage_case1()
+ {
+ //Arrange
+
+ Updates updates = new Updates
+ {
+ Type = "confirmation"
+ };
+
+ const string confirmationMessage = "uhyuhu";
+
+ iConfiguration.SetupGet(configuration => configuration[It.IsAny()])
+ .Returns(confirmationMessage);
+
+ var vkResponseClientService = new VkResponseClientService(iVkApi.Object,
+ iConfiguration.Object, iCurrencyProvider.Object);
+
+ //Act
+
+ var actualResult = await vkResponseClientService.SendResponse(updates);
+
+ //Assert
+
+ Assert.Equal(actualResult, confirmationMessage);
+ }
+
+ [Fact]
+ public async Task SendMessageNull()
+ {
+ //Arrange
+
+ Updates updates = null;
+
+ var vkResponseClientService = new VkResponseClientService(iVkApi.Object,
+ iConfiguration.Object, iCurrencyProvider.Object);
+
+ //Act
+
+ var actualResult = await vkResponseClientService.SendResponse(updates);
+
+ //Assert
+
+ Assert.Equal(string.Empty, actualResult);
+ }
+
+ [Fact]
+ public async Task SendMessage_case2()
+ {
+ //Arrange
+
+ Updates updates = new Updates
+ {
+ Type = "message_new",
+ Object = new JObject()
+ };
+
+ //iVkApi.SetupGet(iVkApi => iVkApi[It.IsAny()]).Returns();
+
+ CurrencyExchangeRate[] currencyExchangeRates =
+ {
+ new CurrencyExchangeRate
+ {
+ Name = "ggg",
+ Value = 2.4
+ },
+ new CurrencyExchangeRate
+ {
+ Name = "qqq",
+ Value = 2.4
+ },
+ new CurrencyExchangeRate
+ {
+ Name = "aaa",
+ Value = 2.4
+ }
+ };
+
+ iCurrencyProvider.Setup(currencyProvider => currencyProvider.GetExchangeRateAsync()).ReturnsAsync(
+ currencyExchangeRates);
+
+
+ string expectedResult =
+ $"{currencyExchangeRates[0].Name}: {currencyExchangeRates[0].Value} ₽\n{currencyExchangeRates[1].Name}: {currencyExchangeRates[1].Value} ₽\n{currencyExchangeRates[2].Name}: {currencyExchangeRates[2].Value} ₽\n";
+
+ var vkResponseClientService = new VkResponseClientService(iVkApi.Object,
+ iConfiguration.Object, iCurrencyProvider.Object);
+
+ //Act
+
+ string actualResult = await vkResponseClientService.SendResponse(updates);
+
+
+ //Assert
+
+ Assert.Equal(expectedResult, actualResult);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ConsoleAppCourseValut.sln b/ConsoleAppCourseValut.sln
index 3e29777..9f8bac5 100644
--- a/ConsoleAppCourseValut.sln
+++ b/ConsoleAppCourseValut.sln
@@ -3,24 +3,66 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.452
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleAppCourseCurrency", "ConsoleAppCourseValut\ConsoleAppCourseCurrency.csproj", "{08DA201E-DC1C-4DF9-9A71-55E32B3D0483}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParserСurrency", "ParserСurrency\ParserСurrency.csproj", "{10A225C1-5EAA-40D0-A7E9-48774C1DBFE5}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BusinessLogicLayer", "BusinessLogicLayer", "{723CCBD0-6040-4095-B01B-85F234E7B03D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogicLayer.Abstraction", "BusinessLogicLayer.Abstraction\BusinessLogicLayer.Abstraction.csproj", "{50731D10-9144-4FFC-A0AF-6FCB1C8693B4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogicLayer.Implementation", "BusinessLogicLayer.Implementation\BusinessLogicLayer.Implementation.csproj", "{827E6D5F-C334-4954-BD6D-00AB758C5555}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogicLayer.Objects", "BusinessLogicLayer.Objects\BusinessLogicLayer.Objects.csproj", "{658F15E6-8BB1-4CEE-8F3A-52AEB335C0A8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataAccessLayer", "DataAccessLayer", "{5DEA6744-5DC4-4C77-903A-1A0E32A347F6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccessLayer.Abstraction", "DataAccessLayer.Abstraction\DataAccessLayer.Abstraction.csproj", "{31C8B387-847F-499B-9B1B-F3B87FF65AC3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccessLayer.Implementation", "DataAccessLayer.Implementation\DataAccessLayer.Implementation.csproj", "{0A6427A3-7CC5-4089-930A-485D1CED818A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataAccessLayer.Models", "DataAccessLayer.Models\DataAccessLayer.Models.csproj", "{EEE62B96-2CBB-4ED0-B3BC-319DBE43A8C9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PresentationLayer", "PresentationLayer", "{1800E55A-1231-4FB8-8B06-96D0A7FAEB0C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogicLayer.Tests", "BusinessLogicLayer.Tests\BusinessLogicLayer.Tests.csproj", "{B161200F-7E83-4067-8D2E-B0BED561C72A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {08DA201E-DC1C-4DF9-9A71-55E32B3D0483}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {08DA201E-DC1C-4DF9-9A71-55E32B3D0483}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {08DA201E-DC1C-4DF9-9A71-55E32B3D0483}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {08DA201E-DC1C-4DF9-9A71-55E32B3D0483}.Release|Any CPU.Build.0 = Release|Any CPU
{10A225C1-5EAA-40D0-A7E9-48774C1DBFE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10A225C1-5EAA-40D0-A7E9-48774C1DBFE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10A225C1-5EAA-40D0-A7E9-48774C1DBFE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10A225C1-5EAA-40D0-A7E9-48774C1DBFE5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {50731D10-9144-4FFC-A0AF-6FCB1C8693B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50731D10-9144-4FFC-A0AF-6FCB1C8693B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50731D10-9144-4FFC-A0AF-6FCB1C8693B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50731D10-9144-4FFC-A0AF-6FCB1C8693B4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {827E6D5F-C334-4954-BD6D-00AB758C5555}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {827E6D5F-C334-4954-BD6D-00AB758C5555}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {827E6D5F-C334-4954-BD6D-00AB758C5555}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {827E6D5F-C334-4954-BD6D-00AB758C5555}.Release|Any CPU.Build.0 = Release|Any CPU
+ {658F15E6-8BB1-4CEE-8F3A-52AEB335C0A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {658F15E6-8BB1-4CEE-8F3A-52AEB335C0A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {658F15E6-8BB1-4CEE-8F3A-52AEB335C0A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {658F15E6-8BB1-4CEE-8F3A-52AEB335C0A8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {31C8B387-847F-499B-9B1B-F3B87FF65AC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {31C8B387-847F-499B-9B1B-F3B87FF65AC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {31C8B387-847F-499B-9B1B-F3B87FF65AC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {31C8B387-847F-499B-9B1B-F3B87FF65AC3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A6427A3-7CC5-4089-930A-485D1CED818A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A6427A3-7CC5-4089-930A-485D1CED818A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A6427A3-7CC5-4089-930A-485D1CED818A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A6427A3-7CC5-4089-930A-485D1CED818A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EEE62B96-2CBB-4ED0-B3BC-319DBE43A8C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EEE62B96-2CBB-4ED0-B3BC-319DBE43A8C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EEE62B96-2CBB-4ED0-B3BC-319DBE43A8C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EEE62B96-2CBB-4ED0-B3BC-319DBE43A8C9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B161200F-7E83-4067-8D2E-B0BED561C72A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B161200F-7E83-4067-8D2E-B0BED561C72A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B161200F-7E83-4067-8D2E-B0BED561C72A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B161200F-7E83-4067-8D2E-B0BED561C72A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -28,4 +70,14 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AEC23FCF-85CF-43B0-B3BA-D4FFD2B8D264}
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {50731D10-9144-4FFC-A0AF-6FCB1C8693B4} = {723CCBD0-6040-4095-B01B-85F234E7B03D}
+ {827E6D5F-C334-4954-BD6D-00AB758C5555} = {723CCBD0-6040-4095-B01B-85F234E7B03D}
+ {658F15E6-8BB1-4CEE-8F3A-52AEB335C0A8} = {723CCBD0-6040-4095-B01B-85F234E7B03D}
+ {31C8B387-847F-499B-9B1B-F3B87FF65AC3} = {5DEA6744-5DC4-4C77-903A-1A0E32A347F6}
+ {0A6427A3-7CC5-4089-930A-485D1CED818A} = {5DEA6744-5DC4-4C77-903A-1A0E32A347F6}
+ {EEE62B96-2CBB-4ED0-B3BC-319DBE43A8C9} = {5DEA6744-5DC4-4C77-903A-1A0E32A347F6}
+ {10A225C1-5EAA-40D0-A7E9-48774C1DBFE5} = {1800E55A-1231-4FB8-8B06-96D0A7FAEB0C}
+ {B161200F-7E83-4067-8D2E-B0BED561C72A} = {723CCBD0-6040-4095-B01B-85F234E7B03D}
+ EndGlobalSection
EndGlobal
diff --git a/ConsoleAppCourseValut/CbrResponse.cs b/ConsoleAppCourseValut/CbrResponse.cs
deleted file mode 100644
index cea76f3..0000000
--- a/ConsoleAppCourseValut/CbrResponse.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ConsoleAppCourseCurrency
-{
- public class CbrResponse
- {
- public DateTime Date { get; set; }
-
- public DateTime PreviousDate { get; set; }
-
- public Valute Valute { get; set; }
-
- }
-}
diff --git a/ConsoleAppCourseValut/ConsoleAppCourseCurrency.csproj b/ConsoleAppCourseValut/ConsoleAppCourseCurrency.csproj
deleted file mode 100644
index 94b81ab..0000000
--- a/ConsoleAppCourseValut/ConsoleAppCourseCurrency.csproj
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Library
- netcoreapp2.2
- latest
-
-
-
-
-
-
-
-
-
-
-
diff --git a/DataAccessLayer.Abstraction/DataAccessLayer.Abstraction.csproj b/DataAccessLayer.Abstraction/DataAccessLayer.Abstraction.csproj
new file mode 100644
index 0000000..8b21c23
--- /dev/null
+++ b/DataAccessLayer.Abstraction/DataAccessLayer.Abstraction.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
diff --git a/DataAccessLayer.Implementation/DataAccessLayer.Implementation.csproj b/DataAccessLayer.Implementation/DataAccessLayer.Implementation.csproj
new file mode 100644
index 0000000..fbb67b0
--- /dev/null
+++ b/DataAccessLayer.Implementation/DataAccessLayer.Implementation.csproj
@@ -0,0 +1,11 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
diff --git a/DataAccessLayer.Models/DataAccessLayer.Models.csproj b/DataAccessLayer.Models/DataAccessLayer.Models.csproj
new file mode 100644
index 0000000..72b0981
--- /dev/null
+++ b/DataAccessLayer.Models/DataAccessLayer.Models.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netcoreapp2.2
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DataAccessLayer.Models/Entities/CurrencyExchangeRate.cs b/DataAccessLayer.Models/Entities/CurrencyExchangeRate.cs
new file mode 100644
index 0000000..e0670cf
--- /dev/null
+++ b/DataAccessLayer.Models/Entities/CurrencyExchangeRate.cs
@@ -0,0 +1,18 @@
+using System;
+using DataAccessLayer.Models.Enums;
+
+namespace DataAccessLayer.Models.Entities
+{
+ public class CurrencyExchangeRate
+ {
+ public SourceType DataSource { get; set; }
+
+ public string Code { get; set; }
+
+ public string Name { get; set; }
+
+ public double Value { get; set; }
+
+ public DateTime Date { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DataAccessLayer.Models/Entities/Updates.cs b/DataAccessLayer.Models/Entities/Updates.cs
new file mode 100644
index 0000000..6397489
--- /dev/null
+++ b/DataAccessLayer.Models/Entities/Updates.cs
@@ -0,0 +1,27 @@
+using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace DataAccessLayer.Models.Entities
+{
+ [Serializable]
+ public class Updates
+ {
+ ///
+ /// Тип события
+ ///
+ public string Type { get; set; }
+
+ ///
+ /// Объект, инициировавший событие
+ /// Структура объекта зависит от типа уведомления
+ ///
+ public JObject Object { get; set; }
+
+ ///
+ /// ID сообщества, в котором произошло событие
+ ///
+ [JsonProperty("group_id")]
+ public long GroupId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/DataAccessLayer.Models/Enums/SourceType.cs b/DataAccessLayer.Models/Enums/SourceType.cs
new file mode 100644
index 0000000..da2666b
--- /dev/null
+++ b/DataAccessLayer.Models/Enums/SourceType.cs
@@ -0,0 +1,10 @@
+namespace DataAccessLayer.Models.Enums
+{
+ public enum SourceType
+ {
+ Exchange,
+
+//959d1d77b858e5a8e51c3c4ed3ca06f6 https://currate.ru/api/?get=rates&pairs=USDRUB,EURRUB&key=959d1d77b858e5a8e51c3c4ed3ca06f6
+ Official
+ }
+}
\ No newline at end of file
diff --git a/DataAccessLayer.Models/MapperProfiles/DateResolver.cs b/DataAccessLayer.Models/MapperProfiles/DateResolver.cs
new file mode 100644
index 0000000..207d6e3
--- /dev/null
+++ b/DataAccessLayer.Models/MapperProfiles/DateResolver.cs
@@ -0,0 +1,15 @@
+using System;
+using AutoMapper;
+using BusinessLogicLayer.Objects.Dtos;
+using BusinessLogicLayer.Objects.Dtos.Cbr;
+using DataAccessLayer.Models.Entities;
+
+namespace DataAccessLayer.Models.MapperProfiles
+{
+ public class DateResolver : IValueResolver
+ {
+ public DateTime Resolve(Currency source, CurrencyExchangeRate destination, DateTime destMember,
+ ResolutionContext context) =>
+ context.Items[CbrConstants.Date] as DateTime? ?? DateTime.Today;
+ }
+}
\ No newline at end of file
diff --git a/DataAccessLayer.Models/MapperProfiles/ExchangeRateMappingProfile.cs b/DataAccessLayer.Models/MapperProfiles/ExchangeRateMappingProfile.cs
new file mode 100644
index 0000000..475570e
--- /dev/null
+++ b/DataAccessLayer.Models/MapperProfiles/ExchangeRateMappingProfile.cs
@@ -0,0 +1,23 @@
+using AutoMapper;
+using BusinessLogicLayer.Objects.Dtos.Cbr;
+using DataAccessLayer.Models.Entities;
+using DataAccessLayer.Models.Enums;
+
+namespace DataAccessLayer.Models.MapperProfiles
+{
+ public class ExchangeRateMappingProfile : Profile
+ {
+ public ExchangeRateMappingProfile()
+ {
+ CreateMap()
+ .ForMember(dest => dest.Date, options => options
+ .MapFrom())
+ .ForMember(dest => dest.DataSource, options => options
+ .MapFrom(dto => SourceType.Official))
+ .ForMember(dest => dest.Code, options => options
+ .MapFrom(dto => dto.CharCode))
+ .ForMember(dest => dest.Value, options => options
+ .MapFrom(dto => dto.Value / dto.Nominal));
+ }
+ }
+}
\ No newline at end of file
diff --git "a/Parser\320\241urrency/Controllers/CallbackController.cs" "b/Parser\320\241urrency/Controllers/CallbackController.cs"
index 8e2f691..a16f577 100644
--- "a/Parser\320\241urrency/Controllers/CallbackController.cs"
+++ "b/Parser\320\241urrency/Controllers/CallbackController.cs"
@@ -1,20 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Configuration;
+using Abstraction.Interfaces;
+using DataAccessLayer.Models.Entities;
using Microsoft.AspNetCore.Mvc;
-using VkNet.Abstractions;
-using VkNet.Model;
-using VkNet.Model.RequestParams;
-using VkNet.Utils;
-using ParserСurrency.Models;
-using Flurl.Http;
-using ConsoleAppCourseCurrency;
namespace ParserСurrency.Controllers
{
-
[Route("api/[controller]")]
[ApiController]
public class CallbackController : ControllerBase
@@ -22,47 +11,20 @@ public class CallbackController : ControllerBase
///
/// Конфигурация приложения
///
- private readonly IConfiguration _configuration;
+ private readonly IResponseClient _vkResponseClientService;
- private readonly IVkApi _vkApi;
-
- public CallbackController(IVkApi vkApi, IConfiguration configuration)
+ public CallbackController(IResponseClient vkResponseClientService)
{
- _vkApi = vkApi;
- _configuration = configuration;
+ _vkResponseClientService = vkResponseClientService;
}
[HttpPost]
- public async Task CallbackAsync([FromBody] Updates updates)
+ public IActionResult CallbackAsync(Updates updates)
{
- // Проверяем, что находится в поле "type"
- switch (updates.Type)
- {
- // Если это уведомление для подтверждения адреса
- case "confirmation":
- // Отправляем строку для подтверждения
- return Ok(_configuration["Config:Confirmation"]);
-
- case "message_new":
- {
- // Десериализация
- var msg = Message.FromJson(new VkResponse(updates.Object));
+ var response = _vkResponseClientService.SendResponse(updates);
- CbrResponse cbrResponse = await "https://www.cbr-xml-daily.ru/daily_json.js".GetJsonAsync();
- var currencies = cbrResponse.Valute;
- // Отправим в ответ полученный от пользователя текст
- _vkApi.Messages.Send(new MessagesSendParams
- {
- RandomId = new DateTime().Millisecond,
- PeerId = msg.PeerId.Value,
- Message = $"{currencies.USD}\n{currencies.EUR}\n{currencies.UAH}"
- });
- break;
- }
- }
// Возвращаем "ok" серверу Callback API
- return Ok("ok");
+ return Ok(response);
}
-
}
}
\ No newline at end of file
diff --git "a/Parser\320\241urrency/Models/Updates.cs" "b/Parser\320\241urrency/Models/Updates.cs"
deleted file mode 100644
index a16247c..0000000
--- "a/Parser\320\241urrency/Models/Updates.cs"
+++ /dev/null
@@ -1,33 +0,0 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace ParserСurrency.Models
-{
- [Serializable]
- public class Updates
- {
- ///
- /// Тип события
- ///
- [JsonProperty("type")]
- public string Type { get; set; }
-
- ///
- /// Объект, инициировавший событие
- /// Структура объекта зависит от типа уведомления
- ///
- [JsonProperty("object")]
- public JObject Object { get; set; }
-
- ///
- /// ID сообщества, в котором произошло событие
- ///
- [JsonProperty("group_id")]
- public long GroupId { get; set; }
- }
-
-}
diff --git "a/Parser\320\241urrency/Parser\320\241urrency.csproj" "b/Parser\320\241urrency/Parser\320\241urrency.csproj"
index 6147f1d..93737ab 100644
--- "a/Parser\320\241urrency/Parser\320\241urrency.csproj"
+++ "b/Parser\320\241urrency/Parser\320\241urrency.csproj"
@@ -1,4 +1,4 @@
-
+
netcoreapp2.2
@@ -6,13 +6,19 @@
+
-
+
+
+
+
+
+
diff --git "a/Parser\320\241urrency/Startup.cs" "b/Parser\320\241urrency/Startup.cs"
index 7eacdff..1b44df7 100644
--- "a/Parser\320\241urrency/Startup.cs"
+++ "b/Parser\320\241urrency/Startup.cs"
@@ -1,15 +1,12 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
+using Abstraction.Interfaces;
+using AutoMapper;
+using BusinessLogicLayer.Implementation.Services;
+using DataAccessLayer.Models.MapperProfiles;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
using VkNet;
using VkNet.Abstractions;
using VkNet.Model;
@@ -30,7 +27,8 @@ public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
- services.AddSingleton(sp => {
+ services.AddSingleton(sp =>
+ {
var api = new VkApi();
api.Authorize(new ApiAuthParams
{
@@ -38,8 +36,15 @@ public void ConfigureServices(IServiceCollection services)
});
return api;
});
+
+ services.AddSingleton();
+
+ services.AddSingleton();
+
+ services.AddSingleton();
+
+ services.AddAutoMapper(options => options.AddProfile());
}
-
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -59,4 +64,4 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
app.UseMvc();
}
}
-}
+}
\ No newline at end of file
diff --git "a/Parser\320\241urrency/appsettings.json" "b/Parser\320\241urrency/appsettings.json"
index 533af71..acd02fe 100644
--- "a/Parser\320\241urrency/appsettings.json"
+++ "b/Parser\320\241urrency/appsettings.json"
@@ -1,15 +1,9 @@
-//{
-// "Logging": {
-// "LogLevel": {
-// "Default": "Warning"
-// }
-// },
-// "AllowedHosts": "*"
-//}
{
"Config": {
"AccessToken": "2cc72f081f78376c9bb645e7cd1d28c4a26edb0011e87c012fc776ae6552ae10c8051405f51605b633a3d",
- "Confirmation": "72706f26"
+ "Confirmation": "72706f26",
+ "LinqCbr": "https://www.cbr-xml-daily.ru/daily_json.js",
+ "LinqCurrate": "https://currate.ru/api/?get=rates&pairs=USDRUB,EURRUB&key=959d1d77b858e5a8e51c3c4ed3ca06f6"
},
"Logging": {
"LogLevel": {