Skip to content

Conversation

@LeveretJZ
Copy link

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 ExchangeRateProvider calls 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.

CnbExchangeRateLoader is a CNB-specific service with its own configuration, where we can define the environment-specific BaseUrl and the exchange rate publication time, including the timezone.

GetExchangeRatesAsync returns 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.

LocalDateTimeService was 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.

IRequestHandler allows convenient mocking of HttpClient.

IRateRefreshScheduler provides data-source–specific schedules for refreshing rates, which helps determine cache item expiration times. And RefreshScheduleFactory creates a specific implementation of IRateRefreshScheduler based 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, using HttpClient.GetAsync() would provide more flexibility for handling such errors.

  • The validFor property from the CNB response was not used. It could be combined with the 14:30 refresh time to improve cache invalidation accuracy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant