using Marathon.Application.Abstractions;
using Marathon.Application.Storage;
using Marathon.Infrastructure.Export;
using Marathon.Infrastructure.Persistence.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Marathon.Infrastructure.Persistence;
///
/// DI extension that wires up the persistence layer (DbContext, repositories, exporter).
/// Call this from the host's DI setup — do NOT call from DependencyInjection.cs (Phase 4).
///
public static class PersistenceModule
{
///
/// Registers EF Core DbContext, all repositories and the Excel exporter.
/// Reads Storage:DatabasePath from .
///
public static IServiceCollection AddMarathonPersistence(
this IServiceCollection services,
IConfiguration config)
{
services.AddOptions()
.Bind(config.GetSection(StorageOptions.SectionName))
.ValidateOnStart();
services.AddDbContext((sp, opts) =>
{
var storageOptions = sp.GetRequiredService>().Value;
var dbPath = storageOptions.DatabasePath;
// Ensure the directory exists
var dir = Path.GetDirectoryName(dbPath);
if (!string.IsNullOrEmpty(dir))
Directory.CreateDirectory(dir);
// Configure SQLite with WAL journal mode
opts.UseSqlite(
$"Data Source={dbPath}",
sqliteOpts => sqliteOpts.CommandTimeout(30));
});
// Register initializer — the HOST must resolve this at startup and call InitializeAsync().
// Example in Program.cs:
// using var scope = app.Services.CreateScope();
// await scope.ServiceProvider.GetRequiredService().InitializeAsync();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
return services;
}
}