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