diff --git a/src/CSharpApp.Api/Program.cs b/src/CSharpApp.Api/Program.cs index b0eb6a0..8d1e35f 100644 --- a/src/CSharpApp.Api/Program.cs +++ b/src/CSharpApp.Api/Program.cs @@ -6,8 +6,8 @@ // Add services to the container. // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); -builder.Services.AddDefaultConfiguration(); -builder.Services.AddHttpConfiguration(); +builder.Services.AddDefaultConfiguration(builder.Configuration); +builder.Services.AddHttpConfiguration(builder.Configuration); builder.Services.AddProblemDetails(); builder.Services.AddApiVersioning(); diff --git a/src/CSharpApp.Application/Products/ProductsService.cs b/src/CSharpApp.Application/Products/ProductsService.cs index 0f1d367..91b1cb6 100644 --- a/src/CSharpApp.Application/Products/ProductsService.cs +++ b/src/CSharpApp.Application/Products/ProductsService.cs @@ -6,22 +6,38 @@ public class ProductsService : IProductsService private readonly RestApiSettings _restApiSettings; private readonly ILogger _logger; - public ProductsService(IOptions restApiSettings, + public ProductsService(HttpClient httpClient, IOptions restApiSettings, ILogger logger) { - _httpClient = new HttpClient(); + _httpClient = httpClient; _restApiSettings = restApiSettings.Value; _logger = logger; } public async Task> GetProducts() { - _httpClient.BaseAddress = new Uri(_restApiSettings.BaseUrl!); - var response = await _httpClient.GetAsync(_restApiSettings.Products); - response.EnsureSuccessStatusCode(); - var content = await response.Content.ReadAsStringAsync(); - var res = JsonSerializer.Deserialize>(content); - - return res.AsReadOnly(); + try + { + // If Products path is set, request it; otherwise request root + var path = string.IsNullOrWhiteSpace(_restApiSettings.Products) ? string.Empty : _restApiSettings.Products; + + var response = await _httpClient.GetAsync(path); + response.EnsureSuccessStatusCode(); + var content = await response.Content.ReadAsStringAsync(); + + var options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }; + + var res = JsonSerializer.Deserialize>(content, options) ?? new List(); + + return res.AsReadOnly(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error fetching products from remote API"); + throw; + } } -} \ No newline at end of file +} diff --git a/src/CSharpApp.Infrastructure/Configuration/DefaultConfiguration.cs b/src/CSharpApp.Infrastructure/Configuration/DefaultConfiguration.cs index 376d7cd..f4602d9 100755 --- a/src/CSharpApp.Infrastructure/Configuration/DefaultConfiguration.cs +++ b/src/CSharpApp.Infrastructure/Configuration/DefaultConfiguration.cs @@ -2,16 +2,11 @@ namespace CSharpApp.Infrastructure.Configuration; public static class DefaultConfiguration { - public static IServiceCollection AddDefaultConfiguration(this IServiceCollection services) + public static IServiceCollection AddDefaultConfiguration(this IServiceCollection services, IConfiguration configuration) { - var serviceProvider = services.BuildServiceProvider(); - var configuration = serviceProvider.GetService(); - - services.Configure(configuration!.GetSection(nameof(RestApiSettings))); + services.Configure(configuration.GetSection(nameof(RestApiSettings))); services.Configure(configuration.GetSection(nameof(HttpClientSettings))); - services.AddSingleton(); - return services; } -} \ No newline at end of file +} diff --git a/src/CSharpApp.Infrastructure/Configuration/HttpConfiguration.cs b/src/CSharpApp.Infrastructure/Configuration/HttpConfiguration.cs index b4c5c6e..b5fd89d 100755 --- a/src/CSharpApp.Infrastructure/Configuration/HttpConfiguration.cs +++ b/src/CSharpApp.Infrastructure/Configuration/HttpConfiguration.cs @@ -1,9 +1,29 @@ +using Microsoft.Extensions.Options; + namespace CSharpApp.Infrastructure.Configuration; public static class HttpConfiguration { - public static IServiceCollection AddHttpConfiguration(this IServiceCollection services) + public static IServiceCollection AddHttpConfiguration(this IServiceCollection services, IConfiguration configuration) { + // Register a typed HttpClient for ProductsService using IHttpClientFactory + services.AddHttpClient((sp, client) => + { + var rest = sp.GetRequiredService>().Value; + var httpSettings = sp.GetRequiredService>().Value; + + if (!string.IsNullOrWhiteSpace(rest.BaseUrl)) + { + client.BaseAddress = new Uri(rest.BaseUrl); + } + + // Configure timeout from settings (LifeTime is seconds) + if (httpSettings.LifeTime > 0) + { + client.Timeout = TimeSpan.FromSeconds(httpSettings.LifeTime); + } + }); + return services; } -} \ No newline at end of file +}