From b93ba6be1759b7ebe7b18fbeafa33b6813e36d1b Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 5 May 2025 16:11:29 +0200 Subject: [PATCH] Refactor envelope creation logic and add IEnvelopeExecutor Updated CreateEnvelopeCommandHandler to use IEnvelopeExecutor for managing envelope creation. Introduced CreateParmas method for parameter handling in CreateEnvelopeSQL. Corrected Dapper type mapping method name and added service registration for IEnvelopeExecutor in DependencyExtensions. Refactored SQLExecutor to enhance encapsulation. Created EnvelopeExecutor class implementing IEnvelopeExecutor for dedicated envelope operations. --- .../SQLExecutor/IEnvelopeExecutor.cs | 19 ++++++++ .../Commands/CreateEnvelopeCommandHandler.cs | 12 +++--- .../SQL/CreateEnvelopeSQL.cs | 33 +++++++++++--- .../DependencyExtensions.cs | 16 ++++--- .../Executor/EnvelopeExecutor.cs | 43 +++++++++++++++++++ .../Executor/SQLExecutor.cs | 12 +++--- 6 files changed, 111 insertions(+), 24 deletions(-) create mode 100644 EnvelopeGenerator.Application/Contracts/SQLExecutor/IEnvelopeExecutor.cs create mode 100644 EnvelopeGenerator.Infrastructure/Executor/EnvelopeExecutor.cs diff --git a/EnvelopeGenerator.Application/Contracts/SQLExecutor/IEnvelopeExecutor.cs b/EnvelopeGenerator.Application/Contracts/SQLExecutor/IEnvelopeExecutor.cs new file mode 100644 index 00000000..f197cadf --- /dev/null +++ b/EnvelopeGenerator.Application/Contracts/SQLExecutor/IEnvelopeExecutor.cs @@ -0,0 +1,19 @@ +using Dapper; +using EnvelopeGenerator.Domain.Entities; + +namespace EnvelopeGenerator.Application.Contracts.SQLExecutor; + +/// +/// +/// +public interface IEnvelopeExecutor : ISQLExecutor +{ + /// + /// + /// + /// + /// + /// + /// + Task CreateEnvelopeAsync(DynamicParameters parameters, bool addUser = true, CancellationToken cancellation = default); +} diff --git a/EnvelopeGenerator.Application/Envelopes/Commands/CreateEnvelopeCommandHandler.cs b/EnvelopeGenerator.Application/Envelopes/Commands/CreateEnvelopeCommandHandler.cs index 7ac1c166..a4b7d698 100644 --- a/EnvelopeGenerator.Application/Envelopes/Commands/CreateEnvelopeCommandHandler.cs +++ b/EnvelopeGenerator.Application/Envelopes/Commands/CreateEnvelopeCommandHandler.cs @@ -1,8 +1,6 @@ using AutoMapper; -using Dapper; using EnvelopeGenerator.Application.Contracts.SQLExecutor; using EnvelopeGenerator.Application.SQL; -using EnvelopeGenerator.Domain.Entities; using MediatR; namespace EnvelopeGenerator.Application.Envelopes.Commands; @@ -12,18 +10,18 @@ namespace EnvelopeGenerator.Application.Envelopes.Commands; /// public class CreateEnvelopeCommandHandler : IRequestHandler { - private readonly ISQLExecutor _sqlExecutor; + private readonly IEnvelopeExecutor _envelopeExecutor; private readonly IMapper _mapper; /// /// /// - /// + /// /// - public CreateEnvelopeCommandHandler(ISQLExecutor sqlExecutor, IMapper mapper) + public CreateEnvelopeCommandHandler(IEnvelopeExecutor envelopeExecutor, IMapper mapper) { - _sqlExecutor = sqlExecutor; + _envelopeExecutor = envelopeExecutor; _mapper = mapper; } @@ -37,7 +35,7 @@ public class CreateEnvelopeCommandHandler : IRequestHandler(userId, request.Title, request.Message, request.TFAEnabled, cancellationToken); + var envelope = await _envelopeExecutor.CreateEnvelopeAsync(userId, request.Title, request.Message, request.TFAEnabled, cancellationToken); return _mapper.Map(envelope); } diff --git a/EnvelopeGenerator.Application/SQL/CreateEnvelopeSQL.cs b/EnvelopeGenerator.Application/SQL/CreateEnvelopeSQL.cs index fb231334..14f70af3 100644 --- a/EnvelopeGenerator.Application/SQL/CreateEnvelopeSQL.cs +++ b/EnvelopeGenerator.Application/SQL/CreateEnvelopeSQL.cs @@ -34,6 +34,16 @@ public class CreateEnvelopeSQL : ISQL /// public static class Extension { + private static DynamicParameters CreateParmas(int userId, string title = "", string message = "", bool tfaEnabled = false) + { + var parameters = new DynamicParameters(); + parameters.Add("@UserId", userId); + parameters.Add("@Title", title); + parameters.Add("@TfaEnabled", tfaEnabled ? 1 : 0); + parameters.Add("@Message", message); + return parameters; + } + /// /// /// @@ -48,13 +58,26 @@ public static class Extension public static async Task CreateEnvelopeAsync(this ISQLExecutor executor, int userId, string title = "", string message = "", bool tfaEnabled = false, CancellationToken cancellation = default) where TEntity : class { - var parameters = new DynamicParameters(); - parameters.Add("@UserId", userId); - parameters.Add("@Title", title); - parameters.Add("@TfaEnabled", tfaEnabled ? 1 : 0); - parameters.Add("@Message", message); + var parameters = CreateParmas(userId, title, message, tfaEnabled); var envelopes = await executor.Execute(parameters, cancellation); return envelopes.FirstOrDefault(); } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static async Task CreateEnvelopeAsync(this IEnvelopeExecutor executor, int userId, string title = "", string message = "", bool tfaEnabled = false, CancellationToken cancellation = default) + { + var parameters = CreateParmas(userId, title, message, tfaEnabled); + + return await executor.CreateEnvelopeAsync(parameters, cancellation: cancellation); + } } \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs b/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs index dd8458ed..d9d3bd92 100644 --- a/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs +++ b/EnvelopeGenerator.Infrastructure/DependencyExtensions.cs @@ -12,6 +12,7 @@ using EnvelopeGenerator.Infrastructure.Executor; using Dapper; using System.ComponentModel.DataAnnotations.Schema; using System.Reflection; +using DigitalData.UserManager.Domain.Entities; namespace EnvelopeGenerator.Infrastructure; @@ -74,11 +75,14 @@ public static class DIExtensions services.AddSQLExecutor(); services.AddSQLExecutor(); - SetDappeTypeMap(); - SetDappeTypeMap(); - SetDappeTypeMap(); - SetDappeTypeMap(); - SetDappeTypeMap(); + SetDapperTypeMap(); + SetDapperTypeMap(); + SetDapperTypeMap(); + SetDapperTypeMap(); + SetDapperTypeMap(); + SetDapperTypeMap(); + + services.AddScoped(); if (sqlExecutorConfiguration is not null || sqlExecutorConfigureOptions is not null) services.AddSQLExecutor(sqlExecutorConfiguration, sqlExecutorConfigureOptions); @@ -100,7 +104,7 @@ public static class DIExtensions return services.AddSingleton(); } - private static void SetDappeTypeMap() + private static void SetDapperTypeMap() { Dapper.SqlMapper.SetTypeMap(typeof(TModel), new CustomPropertyTypeMap( typeof(TModel), diff --git a/EnvelopeGenerator.Infrastructure/Executor/EnvelopeExecutor.cs b/EnvelopeGenerator.Infrastructure/Executor/EnvelopeExecutor.cs new file mode 100644 index 00000000..c178eb0b --- /dev/null +++ b/EnvelopeGenerator.Infrastructure/Executor/EnvelopeExecutor.cs @@ -0,0 +1,43 @@ +using Dapper; +using DigitalData.UserManager.Application.Contracts.Repositories; +using DigitalData.UserManager.Infrastructure.Repositories; +using EnvelopeGenerator.Application.Contracts.SQLExecutor; +using EnvelopeGenerator.Application.SQL; +using EnvelopeGenerator.Domain.Entities; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace EnvelopeGenerator.Infrastructure.Executor; + +public class EnvelopeExecutor : SQLExecutor, IEnvelopeExecutor +{ + private readonly IUserRepository _userRepository; + + public EnvelopeExecutor(ILogger logger, IServiceProvider provider, IOptions sqlExecutorParamsOptions, IUserRepository userRepository) : base(provider, sqlExecutorParamsOptions) + { + _userRepository = userRepository; + } + + public async Task CreateEnvelopeAsync(DynamicParameters parameters, bool addUser = true, CancellationToken cancellation = default) + { + using var connection = new SqlConnection(Params.ConnectionString); + var sql = Provider.GetRequiredService(); + await connection.OpenAsync(cancellation); + var envelopes = await connection.QueryAsync(sql.Raw, parameters); + var envelope = envelopes.FirstOrDefault(); + + if (envelope is null) + return null; + + // Add User + if (addUser) + { + var user = await _userRepository.ReadByIdAsync(envelope.UserId); + envelope.User = user; + } + + return envelope; + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Infrastructure/Executor/SQLExecutor.cs b/EnvelopeGenerator.Infrastructure/Executor/SQLExecutor.cs index c8edeeff..5b8a0a3f 100644 --- a/EnvelopeGenerator.Infrastructure/Executor/SQLExecutor.cs +++ b/EnvelopeGenerator.Infrastructure/Executor/SQLExecutor.cs @@ -8,26 +8,26 @@ namespace EnvelopeGenerator.Infrastructure.Executor; public class SQLExecutor : ISQLExecutor { - private readonly SQLExecutorParams _params; + protected readonly SQLExecutorParams Params; - private readonly IServiceProvider _provider; + protected readonly IServiceProvider Provider; public SQLExecutor(IServiceProvider provider, IOptions sqlExecutorParamsOptions) { - _provider = provider; - _params = sqlExecutorParamsOptions.Value; + Provider = provider; + Params = sqlExecutorParamsOptions.Value; } public async Task> Execute(string sql, DynamicParameters parameters, CancellationToken cancellation = default) { - using var connection = new SqlConnection(_params.ConnectionString); + using var connection = new SqlConnection(Params.ConnectionString); await connection.OpenAsync(cancellation); return await connection.QueryAsync(sql, parameters); } public Task> Execute(DynamicParameters parameters, CancellationToken cancellation = default) where TSQL : ISQL { - var sql = _provider.GetRequiredService(); + var sql = Provider.GetRequiredService(); return Execute(sql.Raw, parameters, cancellation); } } \ No newline at end of file