Refactor envelope creation logic and SQL execution
- Changed `_sqlExecutor` type in `CreateEnvelopeCommandHandler` to non-generic `ISQLExecutor`. - Updated `Handle` method to use `CreateEnvelopeAsync` for simplified parameter handling. - Restructured `CreateEnvelopeSQL` to implement `ISQL<Envelope>` with a raw SQL command for creating envelopes. - Added `SetDappeTypeMap<TModel>` method in `DependencyExtensions` for Dapper type mappings. - Improved overall code structure for better separation of concerns and maintainability.
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||||
|
using EnvelopeGenerator.Application.SQL;
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, CreateEnvelopeResponse?>
|
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, CreateEnvelopeResponse?>
|
||||||
{
|
{
|
||||||
private readonly ISQLExecutor<Envelope> _sqlExecutor;
|
private readonly ISQLExecutor _sqlExecutor;
|
||||||
|
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
@@ -35,14 +35,10 @@ public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeComman
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<CreateEnvelopeResponse?> Handle(CreateEnvelopeCommand request, CancellationToken cancellationToken)
|
public async Task<CreateEnvelopeResponse?> Handle(CreateEnvelopeCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var parameters = new DynamicParameters();
|
int userId = request.UserId ?? throw new InvalidOperationException("UserId cannot be null when creating an envelope.");
|
||||||
parameters.Add("@UserId", request.UserId);
|
|
||||||
parameters.Add("@Title", request.Title);
|
|
||||||
parameters.Add("@TfaEnabled", request.TFAEnabled ? 1 : 0);
|
|
||||||
parameters.Add("@Message", request.Message);
|
|
||||||
|
|
||||||
var envelopes = await _sqlExecutor.Execute<Envelope, CreateEnvelopeSQL>(parameters, cancellationToken);
|
var envelope = await _sqlExecutor.CreateEnvelopeAsync<Envelope>(userId, request.Title, request.Message, request.TFAEnabled, cancellationToken);
|
||||||
|
|
||||||
return _mapper.Map<CreateEnvelopeResponse>(envelopes.FirstOrDefault());
|
return _mapper.Map<CreateEnvelopeResponse>(envelope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
|
||||||
using EnvelopeGenerator.Domain.Entities;
|
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class CreateEnvelopeSQL : ISQL<Envelope>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string Raw => @"
|
|
||||||
USE [DD_ECM];
|
|
||||||
DECLARE @OUT_UID varchar(36);
|
|
||||||
|
|
||||||
EXEC [dbo].[PRSIG_API_CREATE_ENVELOPE]
|
|
||||||
@USER_ID = @UserId,
|
|
||||||
@TITLE = @Title,
|
|
||||||
@TFAEnabled = @TfaEnabled,
|
|
||||||
@MESSAGE = @Message,
|
|
||||||
@OUT_UID = @OUT_UID OUTPUT;
|
|
||||||
|
|
||||||
SELECT TOP(1) *
|
|
||||||
FROM [dbo].[TBSIG_ENVELOPE]
|
|
||||||
WHERE [ENVELOPE_UUID] = @OUT_UID;
|
|
||||||
";
|
|
||||||
}
|
|
||||||
60
EnvelopeGenerator.Application/SQL/CreateEnvelopeSQL.cs
Normal file
60
EnvelopeGenerator.Application/SQL/CreateEnvelopeSQL.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using Dapper;
|
||||||
|
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||||
|
using EnvelopeGenerator.Domain.Entities;
|
||||||
|
|
||||||
|
namespace EnvelopeGenerator.Application.SQL;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class CreateEnvelopeSQL : ISQL<Envelope>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string Raw => @"
|
||||||
|
USE [DD_ECM];
|
||||||
|
DECLARE @OUT_UID varchar(36);
|
||||||
|
|
||||||
|
EXEC [dbo].[PRSIG_API_CREATE_ENVELOPE]
|
||||||
|
@USER_ID = @UserId,
|
||||||
|
@TITLE = @Title,
|
||||||
|
@TFAEnabled = @TfaEnabled,
|
||||||
|
@MESSAGE = @Message,
|
||||||
|
@OUT_UID = @OUT_UID OUTPUT;
|
||||||
|
|
||||||
|
SELECT TOP(1) *
|
||||||
|
FROM [dbo].[TBSIG_ENVELOPE]
|
||||||
|
WHERE [ENVELOPE_UUID] = @OUT_UID;
|
||||||
|
";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public static class Extension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEntity"></typeparam>
|
||||||
|
/// <param name="executor"></param>
|
||||||
|
/// <param name="userId"></param>
|
||||||
|
/// <param name="title"></param>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="tfaEnabled"></param>
|
||||||
|
/// <param name="cancellation"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<TEntity?> CreateEnvelopeAsync<TEntity>(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 envelopes = await executor.Execute<TEntity, CreateEnvelopeSQL>(parameters, cancellation);
|
||||||
|
return envelopes.FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,9 @@ using DigitalData.Core.Infrastructure.AutoMapper;
|
|||||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using EnvelopeGenerator.Infrastructure.Executor;
|
using EnvelopeGenerator.Infrastructure.Executor;
|
||||||
|
using Dapper;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.Infrastructure;
|
namespace EnvelopeGenerator.Infrastructure;
|
||||||
|
|
||||||
@@ -71,6 +74,12 @@ public static class DIExtensions
|
|||||||
services.AddSQLExecutor<DocumentReceiverElement>();
|
services.AddSQLExecutor<DocumentReceiverElement>();
|
||||||
services.AddSQLExecutor<DocumentStatus>();
|
services.AddSQLExecutor<DocumentStatus>();
|
||||||
|
|
||||||
|
SetDappeTypeMap<Envelope>();
|
||||||
|
SetDappeTypeMap<Receiver>();
|
||||||
|
SetDappeTypeMap<EnvelopeDocument>();
|
||||||
|
SetDappeTypeMap<DocumentReceiverElement>();
|
||||||
|
SetDappeTypeMap<DocumentStatus>();
|
||||||
|
|
||||||
if (sqlExecutorConfiguration is not null || sqlExecutorConfigureOptions is not null)
|
if (sqlExecutorConfiguration is not null || sqlExecutorConfigureOptions is not null)
|
||||||
services.AddSQLExecutor(sqlExecutorConfiguration, sqlExecutorConfigureOptions);
|
services.AddSQLExecutor(sqlExecutorConfiguration, sqlExecutorConfigureOptions);
|
||||||
|
|
||||||
@@ -91,6 +100,22 @@ public static class DIExtensions
|
|||||||
return services.AddSingleton<ISQLExecutor, SQLExecutor>();
|
return services.AddSingleton<ISQLExecutor, SQLExecutor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void SetDappeTypeMap<TModel>()
|
||||||
|
{
|
||||||
|
Dapper.SqlMapper.SetTypeMap(typeof(TModel), new CustomPropertyTypeMap(
|
||||||
|
typeof(TModel),
|
||||||
|
(type, columnName) =>
|
||||||
|
{
|
||||||
|
return type.GetProperties().FirstOrDefault(prop =>
|
||||||
|
{
|
||||||
|
var attr = prop.GetCustomAttribute<ColumnAttribute>();
|
||||||
|
return attr != null && string.Equals(attr.Name, columnName, StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| string.Equals(prop.Name, columnName, StringComparison.OrdinalIgnoreCase);
|
||||||
|
})!;
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddSQLExecutor<T>(this IServiceCollection services, IConfiguration? configuration = null, Action<SQLExecutorParams>? configureOptions = null) where T : class
|
public static IServiceCollection AddSQLExecutor<T>(this IServiceCollection services, IConfiguration? configuration = null, Action<SQLExecutorParams>? configureOptions = null) where T : class
|
||||||
{
|
{
|
||||||
if (configuration is not null && configureOptions is not null)
|
if (configuration is not null && configureOptions is not null)
|
||||||
|
|||||||
Reference in New Issue
Block a user