ExchangeRateProvider Implementation for Daily Exchange Rates Loading #789
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
ExchangeRateProvider Implementation for Daily Exchange Rates Loading
I decided not to create separate projects for different application layers, as I was encouraged to keep the final solution simple and avoid spending excessive time on the task.
The
ExchangeRateProvidercalls a CNB-specific loader, which makes it easy to extend the provider to work with multiple data sources if such a requirement appears later.A memory cache is used within the provider to improve performance by keeping the loaded rates until the next scheduled refresh time.
CnbExchangeRateLoaderis a CNB-specific service with its own configuration, where we can define the environment-specificBaseUrland the exchange rate publication time, including the timezone.GetExchangeRatesAsyncreturns exchange rates for the specified date and currencies. It loads all available rates for the given date and filters out non-requested currencies from the result list, since the bank API does not provide a method to query specific currencies.LocalDateTimeServicewas introduced to avoid flaky test issues. If needed, this service can also be extended to return dates in specific time zones based on conditions such as regional settings or user profiles.IRequestHandlerallows convenient mocking ofHttpClient.IRateRefreshSchedulerprovides data-source–specific schedules for refreshing rates, which helps determine cache item expiration times. AndRefreshScheduleFactorycreates a specific implementation ofIRateRefreshSchedulerbased on the configuration section passed to the factory.Considerations Not Implemented for Simplicity
Retry logic when loading rates — useful in cases where the bank API is unstable. Implementing retries would also require adding a
CancellationToken.Using
HttpClient.GetStream()for simplicity. This approach does not allow retrieving the full response body in case of HTTP errors. Since the CNB API returns a JSON body containing error details for 400/500 errors, usingHttpClient.GetAsync()would provide more flexibility for handling such errors.The
validForproperty from the CNB response was not used. It could be combined with the 14:30 refresh time to improve cache invalidation accuracy.