Refactor to inject IConfigurationService directly instead of using factory singletons
Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com>
This commit is contained in:
parent
98fc96af90
commit
38096910d0
7 changed files with 30 additions and 16 deletions
|
|
@ -12,20 +12,20 @@ namespace ShiftScheduler.Server.Controllers
|
||||||
private readonly IcsExportService _icsService;
|
private readonly IcsExportService _icsService;
|
||||||
private readonly PdfExportService _pdfExportService;
|
private readonly PdfExportService _pdfExportService;
|
||||||
private readonly ITransportService _transportService;
|
private readonly ITransportService _transportService;
|
||||||
private readonly TransportConfiguration _transportConfig;
|
private readonly IConfigurationService _configurationService;
|
||||||
|
|
||||||
public ShiftController(
|
public ShiftController(
|
||||||
ShiftService shiftService,
|
ShiftService shiftService,
|
||||||
IcsExportService icsService,
|
IcsExportService icsService,
|
||||||
PdfExportService pdfExportService,
|
PdfExportService pdfExportService,
|
||||||
ITransportService transportService,
|
ITransportService transportService,
|
||||||
TransportConfiguration transportConfig)
|
IConfigurationService configurationService)
|
||||||
{
|
{
|
||||||
_shiftService = shiftService;
|
_shiftService = shiftService;
|
||||||
_icsService = icsService;
|
_icsService = icsService;
|
||||||
_pdfExportService = pdfExportService;
|
_pdfExportService = pdfExportService;
|
||||||
_transportService = transportService;
|
_transportService = transportService;
|
||||||
_transportConfig = transportConfig;
|
_configurationService = configurationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("shifts")]
|
[HttpGet("shifts")]
|
||||||
|
|
@ -43,6 +43,7 @@ namespace ShiftScheduler.Server.Controllers
|
||||||
return NotFound($"Shift '{request.ShiftName}' not found");
|
return NotFound($"Shift '{request.ShiftName}' not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var transportConfig = _configurationService.GetTransportConfiguration();
|
||||||
TransportConnection? morningTransport = null;
|
TransportConnection? morningTransport = null;
|
||||||
TransportConnection? afternoonTransport = null;
|
TransportConnection? afternoonTransport = null;
|
||||||
|
|
||||||
|
|
@ -71,7 +72,7 @@ namespace ShiftScheduler.Server.Controllers
|
||||||
if (morningEndTime.HasValue && afternoonStartTime.HasValue)
|
if (morningEndTime.HasValue && afternoonStartTime.HasValue)
|
||||||
{
|
{
|
||||||
var breakDurationMinutes = (afternoonStartTime.Value - morningEndTime.Value).TotalMinutes;
|
var breakDurationMinutes = (afternoonStartTime.Value - morningEndTime.Value).TotalMinutes;
|
||||||
shouldLoadAfternoonTransport = breakDurationMinutes >= _transportConfig.MinBreakMinutes;
|
shouldLoadAfternoonTransport = breakDurationMinutes >= transportConfig.MinBreakMinutes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ var appConfiguration = new ApplicationConfiguration
|
||||||
|
|
||||||
// Register services
|
// Register services
|
||||||
builder.Services.AddSingleton<IConfigurationService>(new ConfigurationService(appConfiguration));
|
builder.Services.AddSingleton<IConfigurationService>(new ConfigurationService(appConfiguration));
|
||||||
builder.Services.AddSingleton<List<Shift>>(provider => provider.GetRequiredService<IConfigurationService>().GetShifts());
|
|
||||||
builder.Services.AddSingleton<TransportConfiguration>(provider => provider.GetRequiredService<IConfigurationService>().GetTransportConfiguration());
|
|
||||||
builder.Services.AddMemoryCache();
|
builder.Services.AddMemoryCache();
|
||||||
builder.Services.AddHttpClient<TransportApiService>();
|
builder.Services.AddHttpClient<TransportApiService>();
|
||||||
builder.Services.AddSingleton<ShiftService>();
|
builder.Services.AddSingleton<ShiftService>();
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ namespace ShiftScheduler.Services
|
||||||
{
|
{
|
||||||
public class ShiftService
|
public class ShiftService
|
||||||
{
|
{
|
||||||
private readonly List<Shift> _shifts;
|
private readonly IConfigurationService _configurationService;
|
||||||
|
|
||||||
public ShiftService(List<Shift> shifts)
|
public ShiftService(IConfigurationService configurationService)
|
||||||
{
|
{
|
||||||
_shifts = shifts;
|
_configurationService = configurationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Shift> GetShifts() => _shifts;
|
public List<Shift> GetShifts() => _configurationService.GetShifts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@ using ShiftScheduler.Shared;
|
||||||
|
|
||||||
namespace ShiftScheduler.Services
|
namespace ShiftScheduler.Services
|
||||||
{
|
{
|
||||||
public class TransportApiService(HttpClient httpClient, TransportConfiguration config) : ITransportApiService
|
public class TransportApiService(HttpClient httpClient, IConfigurationService configurationService) : ITransportApiService
|
||||||
{
|
{
|
||||||
public async Task<TransportConnection?> GetConnectionAsync(DateTime shiftStartTime)
|
public async Task<TransportConnection?> GetConnectionAsync(DateTime shiftStartTime)
|
||||||
{
|
{
|
||||||
|
var config = configurationService.GetTransportConfiguration();
|
||||||
|
|
||||||
// To allow connections that arrive after shift starts, we search from earlier time
|
// To allow connections that arrive after shift starts, we search from earlier time
|
||||||
// and request more connections to cover the full range
|
// and request more connections to cover the full range
|
||||||
var searchDate = shiftStartTime.ToString("yyyy-MM-dd");
|
var searchDate = shiftStartTime.ToString("yyyy-MM-dd");
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,16 @@ using ShiftScheduler.Shared;
|
||||||
|
|
||||||
namespace ShiftScheduler.Services
|
namespace ShiftScheduler.Services
|
||||||
{
|
{
|
||||||
public class TransportService(ITransportApiService transportService, TransportConfiguration config, IMemoryCache cache) : ITransportService
|
public class TransportService(ITransportApiService transportService, IConfigurationService configurationService, IMemoryCache cache) : ITransportService
|
||||||
{
|
{
|
||||||
public async Task<TransportConnection?> GetConnectionAsync(DateTime shiftStartTime)
|
public async Task<TransportConnection?> GetConnectionAsync(DateTime shiftStartTime)
|
||||||
{
|
{
|
||||||
|
var config = configurationService.GetTransportConfiguration();
|
||||||
var searchDate = shiftStartTime.ToString("yyyy-MM-dd");
|
var searchDate = shiftStartTime.ToString("yyyy-MM-dd");
|
||||||
var searchTime = shiftStartTime.AddMinutes(config.MaxLateArrivalMinutes).ToString("HH:mm");
|
var searchTime = shiftStartTime.AddMinutes(config.MaxLateArrivalMinutes).ToString("HH:mm");
|
||||||
|
|
||||||
// Generate cache key based on request parameters
|
// Generate cache key based on request parameters
|
||||||
var cacheKey = GenerateCacheKey(searchDate, searchTime);
|
var cacheKey = GenerateCacheKey(config, searchDate, searchTime);
|
||||||
|
|
||||||
// Try to get from cache first
|
// Try to get from cache first
|
||||||
if (cache.TryGetValue(cacheKey, out TransportConnection? cachedConnection) && cachedConnection != null)
|
if (cache.TryGetValue(cacheKey, out TransportConnection? cachedConnection) && cachedConnection != null)
|
||||||
|
|
@ -35,7 +36,7 @@ namespace ShiftScheduler.Services
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateCacheKey(string searchDate, string searchTime)
|
private string GenerateCacheKey(TransportConfiguration config, string searchDate, string searchTime)
|
||||||
{
|
{
|
||||||
return $"transport_{config.StartStation}_{config.EndStation}_{searchDate}_{searchTime}";
|
return $"transport_{config.StartStation}_{config.EndStation}_{searchDate}_{searchTime}";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ namespace ShiftScheduler.Services.Tests;
|
||||||
public class TransportApiServiceTests
|
public class TransportApiServiceTests
|
||||||
{
|
{
|
||||||
private readonly Mock<HttpMessageHandler> _httpMessageHandlerMock;
|
private readonly Mock<HttpMessageHandler> _httpMessageHandlerMock;
|
||||||
|
private readonly Mock<IConfigurationService> _configurationServiceMock;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly TransportApiService _transportApiService;
|
private readonly TransportApiService _transportApiService;
|
||||||
|
|
||||||
|
|
@ -18,6 +19,7 @@ public class TransportApiServiceTests
|
||||||
{
|
{
|
||||||
_httpMessageHandlerMock = new Mock<HttpMessageHandler>();
|
_httpMessageHandlerMock = new Mock<HttpMessageHandler>();
|
||||||
_httpClient = new HttpClient(_httpMessageHandlerMock.Object);
|
_httpClient = new HttpClient(_httpMessageHandlerMock.Object);
|
||||||
|
_configurationServiceMock = new Mock<IConfigurationService>();
|
||||||
|
|
||||||
var config = new TransportConfiguration
|
var config = new TransportConfiguration
|
||||||
{
|
{
|
||||||
|
|
@ -31,7 +33,11 @@ public class TransportApiServiceTests
|
||||||
CacheDurationDays = 1
|
CacheDurationDays = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
_transportApiService = new TransportApiService(_httpClient, config);
|
_configurationServiceMock
|
||||||
|
.Setup(x => x.GetTransportConfiguration())
|
||||||
|
.Returns(config);
|
||||||
|
|
||||||
|
_transportApiService = new TransportApiService(_httpClient, _configurationServiceMock.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ namespace ShiftScheduler.Services.Tests;
|
||||||
public class TransportServiceTests
|
public class TransportServiceTests
|
||||||
{
|
{
|
||||||
private readonly Mock<ITransportApiService> _transportServiceMock;
|
private readonly Mock<ITransportApiService> _transportServiceMock;
|
||||||
|
private readonly Mock<IConfigurationService> _configurationServiceMock;
|
||||||
private readonly IMemoryCache _memoryCache;
|
private readonly IMemoryCache _memoryCache;
|
||||||
private readonly TransportService _transportService;
|
private readonly TransportService _transportService;
|
||||||
private readonly TransportConfiguration _config;
|
private readonly TransportConfiguration _config;
|
||||||
|
|
@ -16,6 +17,7 @@ public class TransportServiceTests
|
||||||
public TransportServiceTests()
|
public TransportServiceTests()
|
||||||
{
|
{
|
||||||
_transportServiceMock = new Mock<ITransportApiService>();
|
_transportServiceMock = new Mock<ITransportApiService>();
|
||||||
|
_configurationServiceMock = new Mock<IConfigurationService>();
|
||||||
_memoryCache = new MemoryCache(new MemoryCacheOptions());
|
_memoryCache = new MemoryCache(new MemoryCacheOptions());
|
||||||
|
|
||||||
_config = new TransportConfiguration
|
_config = new TransportConfiguration
|
||||||
|
|
@ -30,7 +32,11 @@ public class TransportServiceTests
|
||||||
CacheDurationDays = 1
|
CacheDurationDays = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
_transportService = new TransportService(_transportServiceMock.Object, _config, _memoryCache);
|
_configurationServiceMock
|
||||||
|
.Setup(x => x.GetTransportConfiguration())
|
||||||
|
.Returns(_config);
|
||||||
|
|
||||||
|
_transportService = new TransportService(_transportServiceMock.Object, _configurationServiceMock.Object, _memoryCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue