| | 1 | | using Application.Abstractions; |
| | 2 | | using Application.Currencies.SearchCurrency.Dtos; |
| | 3 | | using Domain.Common; |
| | 4 | | using Domain.Currencies; |
| | 5 | | using MediatR; |
| | 6 | | using Microsoft.Extensions.Logging; |
| | 7 | |
|
| | 8 | | namespace Application.Currencies.SearchCurrency |
| | 9 | | { |
| | 10 | | public class SearchCurrencyHandler : IRequestHandler<SearchCurrencyQuery, Result<SearchCurrencyDto>> |
| | 11 | | { |
| | 12 | | private readonly IExchangeProviderFactory _exchangeFactory; |
| | 13 | | private readonly ILogger<SearchCurrencyHandler> _logger; |
| | 14 | | private readonly ICacheService _cacheService; |
| | 15 | |
|
| 10 | 16 | | public SearchCurrencyHandler(IExchangeProviderFactory exchangeFactory, |
| 10 | 17 | | ILogger<SearchCurrencyHandler> logger, |
| 10 | 18 | | ICacheService cacheService) |
| 10 | 19 | | { |
| 10 | 20 | | _cacheService = cacheService; |
| 10 | 21 | | _exchangeFactory = exchangeFactory; |
| 10 | 22 | | _logger = logger; |
| 10 | 23 | | } |
| | 24 | |
|
| | 25 | | public async Task<Result<SearchCurrencyDto>> Handle(SearchCurrencyQuery command, CancellationToken cancellationT |
| 10 | 26 | | { |
| 10 | 27 | | var currencyCodeResult = CurrencyCode.FromCode(command.CurrencyCode); |
| 10 | 28 | | if (currencyCodeResult.IsFailure) |
| 1 | 29 | | { |
| 1 | 30 | | return Result.Failure<SearchCurrencyDto>(currencyCodeResult.Error); |
| | 31 | | } |
| 9 | 32 | | var currencyCode = currencyCodeResult.Value; |
| 9 | 33 | | var exchangeProvider = _exchangeFactory.GetProvider(ExchangeProviderType.Frankfurter); |
| 9 | 34 | | if (exchangeProvider == null) |
| 1 | 35 | | { |
| 1 | 36 | | _logger.LogError("Could not find an exchange provider, {requestedProvider}", ExchangeProviderType.Frankf |
| 1 | 37 | | return Result.Failure<SearchCurrencyDto>(Error.SystemError); |
| | 38 | | } |
| 8 | 39 | | var cacheKey = $"search-{currencyCode.Value}"; |
| 8 | 40 | | var currencySnapShot = await _cacheService.GetAsync<List<CurrencySnapshot>>(cacheKey, cancellationToken); |
| 8 | 41 | | if (currencySnapShot == null) |
| 6 | 42 | | { |
| 6 | 43 | | var result = await exchangeProvider.SearchAsync(currencyCode, command.StartDate, command.EndDate); |
| 6 | 44 | | if (result.IsFailure) |
| 1 | 45 | | { |
| 1 | 46 | | return Result.Failure<SearchCurrencyDto>(result.Error); |
| | 47 | | } |
| 5 | 48 | | currencySnapShot = result.Value; |
| 5 | 49 | | await _cacheService.SetAsync(cacheKey, currencySnapShot, cancellationToken); |
| 5 | 50 | | } |
| 7 | 51 | | return new SearchCurrencyDto(currencyCode.Value, |
| 7 | 52 | | currencySnapShot.Select(x => |
| 13 | 53 | | new SearchCurrencyDateCapturedDto(x.DateCaptured, |
| 26 | 54 | | x.ExchangeRates.Select(y => new SearchCurrencyAmountDto(y.Code.Value, y.Amount)) |
| 13 | 55 | | .ToList())) |
| 7 | 56 | | .ToList()); |
| 10 | 57 | | } |
| | 58 | | } |
| | 59 | | } |