- Add AutoMapper profile for CfgProfile and ProfileSqlJob entity-to-DTO mappings - Consolidate GetProfileByIdQuery and GetAllActiveProfilesQuery into unified GetProfileQuery - Implement flexible filtering with nullable query options (Id, Active, TypeId, ProfileName) - Add IncludeSqlJobs option for optimized SQL job loading - Move CfgProfileDto to Common/Dtos for better architecture alignment - Add comprehensive unit tests for GetProfileQuery with multiple filter scenarios - Move ISQLExecutor interface from Domain to Application layer - Add GetByIdWithSqlJobsAsync and GetAllActiveWithSqlJobsAsync to repository
115 lines
4.9 KiB
C#
115 lines
4.9 KiB
C#
#if NET48
|
|
using System.Data.Entity;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
#else
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
#endif
|
|
using ECMJobRunner.Application.Common.Interfaces;
|
|
using ECMJobRunner.Domain.Interfaces;
|
|
using ECMJobRunner.Infrastructure.Data;
|
|
using ECMJobRunner.Infrastructure.Repositories;
|
|
using ECMJobRunner.Infrastructure.Services;
|
|
|
|
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>();
|
|
|
|
// Register SQL executor as scoped
|
|
services.AddScoped<ISQLExecutor, SQLExecutor>();
|
|
|
|
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>();
|
|
|
|
// Register SQL executor as scoped
|
|
services.AddScoped<ISQLExecutor, SQLExecutor>();
|
|
|
|
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>();
|
|
|
|
// Register SQL executor as scoped
|
|
services.AddScoped<ISQLExecutor, SQLExecutor>();
|
|
|
|
return services;
|
|
}
|
|
#endif
|
|
}
|
|
}
|