diff --git a/EnvelopeGenerator.GeneratorAPI/Program.cs b/EnvelopeGenerator.GeneratorAPI/Program.cs index bfdb024b..121d83a4 100644 --- a/EnvelopeGenerator.GeneratorAPI/Program.cs +++ b/EnvelopeGenerator.GeneratorAPI/Program.cs @@ -159,7 +159,7 @@ builder.Services.AddCookieBasedLocalizer() ; // Envelope generator serives builder.Services - .AddEnvelopeGeneratorRepositories() + .AddEnvelopeGeneratorInfrastructureServices(sqlExecutorConfigureOptions: executor => executor.ConnectionString = connStr) .AddEnvelopeGeneratorServices(config); var app = builder.Build(); diff --git a/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs b/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs index d15742be..2aeb192a 100644 --- a/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs +++ b/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs @@ -7,6 +7,7 @@ using DigitalData.Core.Infrastructure; using EnvelopeGenerator.Domain.Entities; using DigitalData.Core.Infrastructure.AutoMapper; using EnvelopeGenerator.Application.Contracts.SQLExecutor; +using Microsoft.Extensions.Configuration; namespace EnvelopeGenerator.Infrastructure; @@ -26,7 +27,10 @@ public static class DIExtensions /// This method ensures that the repositories are registered as scoped services, meaning that a new instance of each repository /// will be created per HTTP request (or per scope) within the dependency injection container. /// - public static IServiceCollection AddEnvelopeGeneratorRepositories(this IServiceCollection services, Action? dbContextOptions = null) + public static IServiceCollection AddEnvelopeGeneratorInfrastructureServices(this IServiceCollection services, + Action? dbContextOptions = null, + IConfiguration? sqlExecutorConfiguration = null, + Action? sqlExecutorConfigureOptions = null) { if(dbContextOptions is not null) services.AddDbContext(dbContextOptions); @@ -66,11 +70,34 @@ public static class DIExtensions services.AddSQLExecutor(); services.AddSQLExecutor(); + if (sqlExecutorConfiguration is not null || sqlExecutorConfigureOptions is not null) + services.AddSQLExecutor(sqlExecutorConfiguration, sqlExecutorConfigureOptions); + return services; } - public static IServiceCollection AddSQLExecutor(this IServiceCollection services) where T : class + public static IServiceCollection AddSQLExecutor(this IServiceCollection services, IConfiguration? configuration = null, Action? configureOptions = null) { + if(configuration is not null && configureOptions is not null) + throw new InvalidOperationException("Cannot use both 'configuration' and 'configureOptions'. Only one should be provided."); + + if (configuration is not null) + services.Configure(configuration); + + if(configureOptions is not null) + services.Configure(configureOptions); + + return services.AddSingleton(); + } + + public static IServiceCollection AddSQLExecutor(this IServiceCollection services, IConfiguration? configuration = null, Action? configureOptions = null) where T : class + { + if (configuration is not null && configureOptions is not null) + throw new InvalidOperationException("Cannot use both 'configuration' and 'configureOptions'. Only one should be provided."); + + if (configuration is not null) + services.Configure(configuration); + services.AddScoped, SQLExecutor>(); var interfaceType = typeof(ISQL<>); diff --git a/EnvelopeGenerator.Infrastructure/SQLExecutor.cs b/EnvelopeGenerator.Infrastructure/SQLExecutor.cs index d39f7709..33c3ccfe 100644 --- a/EnvelopeGenerator.Infrastructure/SQLExecutor.cs +++ b/EnvelopeGenerator.Infrastructure/SQLExecutor.cs @@ -2,23 +2,25 @@ using EnvelopeGenerator.Application.Contracts.SQLExecutor; using Microsoft.Data.SqlClient; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; namespace EnvelopeGenerator.Infrastructure; public class SQLExecutor : ISQLExecutor { - private readonly string _cnnStr = "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;"; + private readonly SQLExecutorParams _params; private readonly IServiceProvider _provider; - public SQLExecutor(IServiceProvider provider) + public SQLExecutor(IServiceProvider provider, IOptions sqlExecutorParamsOptions) { _provider = provider; + _params = sqlExecutorParamsOptions.Value; } public async Task> Execute(string sql, DynamicParameters parameters, CancellationToken cancellation = default) { - using var connection = new SqlConnection(_cnnStr); + using var connection = new SqlConnection(_params.ConnectionString); await connection.OpenAsync(cancellation); return await connection.QueryAsync(sql, parameters); } diff --git a/EnvelopeGenerator.Infrastructure/SQLExecutorBaseEntity.cs b/EnvelopeGenerator.Infrastructure/SQLExecutorBaseEntity.cs index cc2c4c26..e1f20d65 100644 --- a/EnvelopeGenerator.Infrastructure/SQLExecutorBaseEntity.cs +++ b/EnvelopeGenerator.Infrastructure/SQLExecutorBaseEntity.cs @@ -1,6 +1,7 @@ using EnvelopeGenerator.Application.Contracts.SQLExecutor; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; namespace EnvelopeGenerator.Infrastructure; @@ -10,7 +11,7 @@ public sealed class SQLExecutor : SQLExecutor, ISQLExecutor where T : clas private readonly IServiceProvider _provider; - public SQLExecutor(EGDbContext context, IServiceProvider provider) : base(provider) + public SQLExecutor(EGDbContext context, IServiceProvider provider, IOptions options) : base(provider, options) { _context = context; _provider = provider; diff --git a/EnvelopeGenerator.Infrastructure/SQLExecutorParams.cs b/EnvelopeGenerator.Infrastructure/SQLExecutorParams.cs new file mode 100644 index 00000000..b2d2f677 --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/SQLExecutorParams.cs @@ -0,0 +1,6 @@ +namespace EnvelopeGenerator.Infrastructure; + +public class SQLExecutorParams +{ + public string? ConnectionString { get; set; } +} diff --git a/EnvelopeGenerator.Terminal/DependencyInjection.cs b/EnvelopeGenerator.Terminal/DependencyInjection.cs index ad011146..421a57d2 100644 --- a/EnvelopeGenerator.Terminal/DependencyInjection.cs +++ b/EnvelopeGenerator.Terminal/DependencyInjection.cs @@ -27,11 +27,11 @@ public static class DependencyInjection }); // Add envelope generator services - services.AddEnvelopeGeneratorRepositories(options => options.UseSqlServer(connStr)); + services.AddEnvelopeGeneratorInfrastructureServices(options => options.UseSqlServer(connStr)); return services .AddSingleton() - .AddEnvelopeGeneratorRepositories() + .AddEnvelopeGeneratorInfrastructureServices() .AddEnvelopeGeneratorServices(configuration) .AddSingleton(sp => { diff --git a/EnvelopeGenerator.Tests.Application/Mock.cs b/EnvelopeGenerator.Tests.Application/Mock.cs index 10bc7ea6..b14108e8 100644 --- a/EnvelopeGenerator.Tests.Application/Mock.cs +++ b/EnvelopeGenerator.Tests.Application/Mock.cs @@ -17,7 +17,7 @@ public class Mock builder.Configuration.AddJsonFile(configPath, optional: true, reloadOnChange: true); builder.Services - .AddEnvelopeGeneratorRepositories(opt => + .AddEnvelopeGeneratorInfrastructureServices(opt => { if (useRealDb) { diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs index 9448b5e4..e9324e3e 100644 --- a/EnvelopeGenerator.Web/Program.cs +++ b/EnvelopeGenerator.Web/Program.cs @@ -90,7 +90,7 @@ try }); // Add envelope generator services - builder.Services.AddEnvelopeGeneratorRepositories(options => options.UseSqlServer(connStr)); + builder.Services.AddEnvelopeGeneratorInfrastructureServices(options => options.UseSqlServer(connStr)); builder.Services.AddEnvelopeGeneratorServices(config);