Introduced a `DbConnection` constructor in `JobRunnerDbContext` for Entity Framework 6 to enable in-memory testing with the Effort library. Added conditional compilation to support both .NET Framework 4.8 and .NET 8. Implemented `AddInfrastructureInMemory` in `DependencyExtension` to register services with in-memory databases: - For .NET 4.8, uses Effort's transient connection. - For .NET 8, uses EF Core's in-memory provider. Registered AutoMapper in both methods for object mapping. Added `EntityMappingProfile` to define AutoMapper configurations, enforcing explicit DTO-to-entity mappings. These changes improve testability and maintainability across .NET versions.
104 lines
4.4 KiB
C#
104 lines
4.4 KiB
C#
#if NET48
|
|
using System.Data.Entity;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
#else
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
#endif
|
|
using ECMJobRunner.Domain.Interfaces;
|
|
using ECMJobRunner.Infrastructure.Data;
|
|
using ECMJobRunner.Infrastructure.Repositories;
|
|
|
|
namespace ECMJobRunner.Infrastructure
|
|
{
|
|
/// <summary>
|
|
/// Dependency injection extension methods for Infrastructure layer
|
|
/// </summary>
|
|
public static class DependencyExtension
|
|
{
|
|
/// <summary>
|
|
/// Add Infrastructure services to dependency injection container
|
|
/// </summary>
|
|
/// <param name="services">Service collection</param>
|
|
/// <param name="connectionString">Database connection string</param>
|
|
/// <returns>Service collection for chaining</returns>
|
|
public static IServiceCollection AddInfrastructure(this IServiceCollection services, string connectionString)
|
|
{
|
|
#if NET48
|
|
// Register DbContext as scoped for EF6 - same pattern as EF Core
|
|
// Each scope (request) gets its own DbContext instance
|
|
services.AddScoped(provider => new JobRunnerDbContext(connectionString));
|
|
#else
|
|
// Register DbContext as scoped for EF Core
|
|
services.AddDbContext<JobRunnerDbContext>(options =>
|
|
options.UseSqlServer(connectionString));
|
|
#endif
|
|
|
|
// Register AutoMapper
|
|
services.AddAutoMapper(typeof(DependencyExtension).Assembly);
|
|
|
|
// Register repositories as scoped (same lifetime as DbContext)
|
|
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
|
|
services.AddScoped<ICfgProfileRepository, CfgProfileRepository>();
|
|
services.AddScoped<IProfileSqlJobRepository, ProfileSqlJobRepository>();
|
|
services.AddScoped<IProfileHistoryRepository, ProfileHistoryRepository>();
|
|
|
|
return services;
|
|
}
|
|
|
|
#if NET48
|
|
/// <summary>
|
|
/// Add Infrastructure services with InMemory database for testing (.NET Framework 4.8 - uses Effort)
|
|
/// </summary>
|
|
/// <param name="services">Service collection</param>
|
|
/// <returns>Service collection for chaining</returns>
|
|
public static IServiceCollection AddInfrastructureInMemory(this IServiceCollection services)
|
|
{
|
|
// Register DbContext as scoped with Effort InMemory connection
|
|
services.AddScoped(provider =>
|
|
{
|
|
var connection = Effort.DbConnectionFactory.CreateTransient();
|
|
return new JobRunnerDbContext(connection);
|
|
});
|
|
|
|
// Register AutoMapper
|
|
services.AddAutoMapper(typeof(DependencyExtension).Assembly);
|
|
|
|
// Register repositories as scoped (same lifetime as DbContext)
|
|
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
|
|
services.AddScoped<ICfgProfileRepository, CfgProfileRepository>();
|
|
services.AddScoped<IProfileSqlJobRepository, ProfileSqlJobRepository>();
|
|
services.AddScoped<IProfileHistoryRepository, ProfileHistoryRepository>();
|
|
|
|
return services;
|
|
}
|
|
#else
|
|
/// <summary>
|
|
/// Add Infrastructure services with InMemory database for testing (.NET 8 - uses EF Core InMemory)
|
|
/// </summary>
|
|
/// <param name="services">Service collection</param>
|
|
/// <param name="databaseName">Optional database name (default: random GUID)</param>
|
|
/// <returns>Service collection for chaining</returns>
|
|
public static IServiceCollection AddInfrastructureInMemory(this IServiceCollection services, string? databaseName = null)
|
|
{
|
|
var dbName = databaseName ?? $"TestDb_{System.Guid.NewGuid()}";
|
|
|
|
// Register DbContext as scoped with InMemory database
|
|
services.AddDbContext<JobRunnerDbContext>(options =>
|
|
options.UseInMemoryDatabase(dbName));
|
|
|
|
// Register AutoMapper
|
|
services.AddAutoMapper(typeof(DependencyExtension).Assembly);
|
|
|
|
// Register repositories as scoped (same lifetime as DbContext)
|
|
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
|
|
services.AddScoped<ICfgProfileRepository, CfgProfileRepository>();
|
|
services.AddScoped<IProfileSqlJobRepository, ProfileSqlJobRepository>();
|
|
services.AddScoped<IProfileHistoryRepository, ProfileHistoryRepository>();
|
|
|
|
return services;
|
|
}
|
|
#endif
|
|
}
|
|
}
|