From 9756303d6ee475b1e750e10d8a3356cce0f5fd0e Mon Sep 17 00:00:00 2001 From: TekH Date: Mon, 30 Jun 2025 13:56:49 +0200 Subject: [PATCH] Refactor repositories and enhance documentation - Mark `IEmailTemplateRepository` and `_repository` in `ReadEmailTemplateQueryHandler` as obsolete, suggesting the use of `IRepository`. - Update `ResetEmailTemplateCommand` with additional documentation and examples for `Type`. - Change return type of `CreateEnvelopeReceiverCommand` to `IRequest`. - Improve caching methods in `CacheExtensions.cs` for better functionality and clarity. - Add XML documentation to the `Ok` method in `MappingExtensions`. - Make `UserReference` property required in `ReadHistoryResponse`. --- .../Repositories/IEmailTemplateRepository.cs | 2 +- .../Reset/ResetEmailTemplateCommand.cs | 27 +- .../Read/ReadEmailTemplateQueryHandler.cs | 5 +- .../Create/CreateEnvelopeReceiverCommand.cs | 2 +- .../CreateEnvelopeReceiverCommandHandler.cs | 2 +- .../Extensions/CacheExtensions.cs | 293 ++++++++++++------ .../Extensions/MappingExtensions.cs | 31 +- .../Queries/Read/ReadHistoryQueryHandler.cs | 4 +- .../Queries/Read/ReadHistoryResponse.cs | 2 +- 9 files changed, 238 insertions(+), 130 deletions(-) diff --git a/EnvelopeGenerator.Application/Contracts/Repositories/IEmailTemplateRepository.cs b/EnvelopeGenerator.Application/Contracts/Repositories/IEmailTemplateRepository.cs index a36de569..73749745 100644 --- a/EnvelopeGenerator.Application/Contracts/Repositories/IEmailTemplateRepository.cs +++ b/EnvelopeGenerator.Application/Contracts/Repositories/IEmailTemplateRepository.cs @@ -7,7 +7,7 @@ namespace EnvelopeGenerator.Application.Contracts.Repositories; /// /// /// -[Obsolete("Use Read-method returning IReadQuery instead.")] +[Obsolete("Use IRepository")] public interface IEmailTemplateRepository : ICRUDRepository { /// diff --git a/EnvelopeGenerator.Application/EmailTemplates/Commands/Reset/ResetEmailTemplateCommand.cs b/EnvelopeGenerator.Application/EmailTemplates/Commands/Reset/ResetEmailTemplateCommand.cs index 1bcfda0e..fa988a54 100644 --- a/EnvelopeGenerator.Application/EmailTemplates/Commands/Reset/ResetEmailTemplateCommand.cs +++ b/EnvelopeGenerator.Application/EmailTemplates/Commands/Reset/ResetEmailTemplateCommand.cs @@ -5,20 +5,19 @@ namespace EnvelopeGenerator.Application.EmailTemplates.Commands.Reset; /// /// Ein Befehl zum Zurücksetzen einer E-Mail-Vorlage auf die Standardwerte. -/// Erbt von und ermöglicht die Angabe einer optionalen ID und eines Typs der E-Mail-Vorlage. +/// Erbt von und ermöglicht die Angabe einer optionalen ID und eines Typs der E-Mail-Vorlage.

+/// Beispiele:
+/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments.
+/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments.
+/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments.
+/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments.
+/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes.
+/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments.
+/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis.
+/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird.
+/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird.
+/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird.
///
-/// Beispiele: -/// 0 - DocumentReceived: Benachrichtigung über den Empfang eines Dokuments. -/// 1 - DocumentSigned: Benachrichtigung über die Unterzeichnung eines Dokuments. -/// 2 - DocumentDeleted: Benachrichtigung über das Löschen eines Dokuments. -/// 3 - DocumentCompleted: Benachrichtigung über den Abschluss eines Dokuments. -/// 4 - DocumentAccessCodeReceived: Benachrichtigung über den Erhalt eines Zugangscodes. -/// 5 - DocumentShared: Benachrichtigung über das Teilen eines Dokuments. -/// 6 - TotpSecret: Benachrichtigung über ein TOTP-Geheimnis. -/// 7 - DocumentRejected_ADM (Für den Absender): Mail an den Absender, wenn das Dokument abgelehnt wird. -/// 8 - DocumentRejected_REC (Für den ablehnenden Empfänger): Mail an den ablehnenden Empfänger, wenn das Dokument abgelehnt wird. -/// 9 - DocumentRejected_REC_2 (Für sonstige Empfänger): Mail an andere Empfänger (Brief), wenn das Dokument abgelehnt wird. -/// public record ResetEmailTemplateCommand : EmailTemplateQuery, IRequest { /// @@ -34,7 +33,7 @@ public record ResetEmailTemplateCommand : EmailTemplateQuery, IRequest /// /// /// Die optionale ID der E-Mail-Vorlage, die zurückgesetzt werden soll. - /// Der Typ der E-Mail-Vorlage, z. B. (optional). + /// Der Typ der E-Mail-Vorlage, z. B. (optional). public ResetEmailTemplateCommand(int? Id = null, Constants.EmailTemplateType? Type = null) : base(Id, Type) { } diff --git a/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateQueryHandler.cs b/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateQueryHandler.cs index 433838dc..84478ee1 100644 --- a/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateQueryHandler.cs +++ b/EnvelopeGenerator.Application/EmailTemplates/Queries/Read/ReadEmailTemplateQueryHandler.cs @@ -12,6 +12,7 @@ public class ReadEmailTemplateQueryHandler : IRequestHandler instead.")] private readonly IEmailTemplateRepository _repository; /// @@ -21,6 +22,7 @@ public class ReadEmailTemplateQueryHandler : IRequestHandler /// Die AutoMapper-Instanz, die zum Zuordnen von Objekten verwendet wird. /// + [Obsolete("Use Read-method returning IReadQuery instead.")] public ReadEmailTemplateQueryHandler(IMapper mapper, IEmailTemplateRepository repository) { _mapper = mapper; @@ -34,6 +36,7 @@ public class ReadEmailTemplateQueryHandler : IRequestHandler /// /// + [Obsolete("Use IRepository")] public async Task Handle(ReadEmailTemplateQuery request, CancellationToken cancellationToken) { var temp = request.Id is int id @@ -46,4 +49,4 @@ public class ReadEmailTemplateQueryHandler : IRequestHandler Receivers, bool TFAEnabled = false - ) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest; \ No newline at end of file + ) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest; \ No newline at end of file diff --git a/EnvelopeGenerator.Application/EnvelopeReceivers/Commands/Create/CreateEnvelopeReceiverCommandHandler.cs b/EnvelopeGenerator.Application/EnvelopeReceivers/Commands/Create/CreateEnvelopeReceiverCommandHandler.cs index 3ab6fda1..b4315258 100644 --- a/EnvelopeGenerator.Application/EnvelopeReceivers/Commands/Create/CreateEnvelopeReceiverCommandHandler.cs +++ b/EnvelopeGenerator.Application/EnvelopeReceivers/Commands/Create/CreateEnvelopeReceiverCommandHandler.cs @@ -64,4 +64,4 @@ public class CreateEnvelopeReceiverCommandHandler : IRequestHandler>(sentRecipients); return res; } -} +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Extensions/CacheExtensions.cs b/EnvelopeGenerator.Application/Extensions/CacheExtensions.cs index 5e9eebd8..16a533c4 100644 --- a/EnvelopeGenerator.Application/Extensions/CacheExtensions.cs +++ b/EnvelopeGenerator.Application/Extensions/CacheExtensions.cs @@ -1,131 +1,222 @@ using Microsoft.Extensions.Caching.Distributed; -namespace EnvelopeGenerator.Application.Extensions +namespace EnvelopeGenerator.Application.Extensions; + +/// +/// +/// +public static class CacheExtensions { - public static class CacheExtensions + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Task SetLongAsync(this IDistributedCache cache, string key, long value, DistributedCacheEntryOptions? options = null, CancellationToken cToken = default) + => options is null + ? cache.SetAsync(key, BitConverter.GetBytes(value), token: cToken) + : cache.SetAsync(key, BitConverter.GetBytes(value), options: options, token: cToken); + + /// + /// + /// + /// + /// + /// + /// + public static async Task GetLongAsync(this IDistributedCache cache, string key, CancellationToken cToken = default) { - public static Task SetLongAsync(this IDistributedCache cache, string key, long value, DistributedCacheEntryOptions? options = null, CancellationToken cToken = default) - => options is null - ? cache.SetAsync(key, BitConverter.GetBytes(value), token: cToken) - : cache.SetAsync(key, BitConverter.GetBytes(value), options: options, token: cToken); + var value = await cache.GetAsync(key, cToken); + return value is null ? null : BitConverter.ToInt64(value, 0); + } - public static async Task GetLongAsync(this IDistributedCache cache, string key, CancellationToken cToken = default) - { - var value = await cache.GetAsync(key, cToken); - return value is null ? null : BitConverter.ToInt64(value, 0); - } + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Task SetDateTimeAsync(this IDistributedCache cache, string key, DateTime value, DistributedCacheEntryOptions? options = null, CancellationToken cToken = default) + => cache.SetLongAsync(key: key, value: value.Ticks, options: options, cToken: cToken); + + /// + /// + /// + /// + /// + /// + /// + public static async Task GetDateTimeAsync(this IDistributedCache cache, string key, CancellationToken cToken = default) + { + var value = await cache.GetAsync(key, cToken); + return value is null ? null : new(BitConverter.ToInt64(value, 0)); + } - public static Task SetDateTimeAsync(this IDistributedCache cache, string key, DateTime value, DistributedCacheEntryOptions? options = null, CancellationToken cToken = default) - => cache.SetLongAsync(key: key, value: value.Ticks, options: options, cToken: cToken); + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static Task SetTimeSpanAsync(this IDistributedCache cache, string key, TimeSpan value, DistributedCacheEntryOptions? options = null, CancellationToken cToken = default) + => cache.SetLongAsync(key: key, value: value.Ticks, options: options, cToken); + + /// + /// + /// + /// + /// + /// + /// + public static async Task GetTimeSpanAsync(this IDistributedCache cache, string key, CancellationToken cToken = default) + { + var value = await cache.GetAsync(key, cToken); + return value is null ? null : new(BitConverter.ToInt64(value, 0)); + } - public static async Task GetDateTimeAsync(this IDistributedCache cache, string key, CancellationToken cToken = default) + //TODO: use code generator + #region GetOrSetAsync + + #region string + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func factory, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) + { + var value = await cache.GetStringAsync(key, cToken); + if (value is null) { - var value = await cache.GetAsync(key, cToken); - return value is null ? null : new(BitConverter.ToInt64(value, 0)); - } + // create new and save + value = factory(); - public static Task SetTimeSpanAsync(this IDistributedCache cache, string key, TimeSpan value, DistributedCacheEntryOptions? options = null, CancellationToken cToken = default) - => cache.SetLongAsync(key: key, value: value.Ticks, options: options, cToken); + Task CacheAsync() => options is null + ? cache.SetStringAsync(key, value, cToken) + : cache.SetStringAsync(key, value, options, cToken); - public static async Task GetTimeSpanAsync(this IDistributedCache cache, string key, CancellationToken cToken = default) - { - var value = await cache.GetAsync(key, cToken); - return value is null ? null : new(BitConverter.ToInt64(value, 0)); + if (cacheInBackground) + _ = Task.Run(async () => await CacheAsync(), cToken); + else + await CacheAsync(); } - //TODO: use code generator - #region GetOrSetAsync + return value; + } - #region string - public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func factory, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func> factoryAsync, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) + { + var value = await cache.GetStringAsync(key, cToken); + if(value is null) { - var value = await cache.GetStringAsync(key, cToken); - if (value is null) - { - // create new and save - value = factory(); - - Task CacheAsync() => options is null - ? cache.SetStringAsync(key, value, cToken) - : cache.SetStringAsync(key, value, options, cToken); - - if (cacheInBackground) - _ = Task.Run(async () => await CacheAsync(), cToken); - else - await CacheAsync(); - } - - return value; - } + // create new and save + value = await factoryAsync(); - public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func> factoryAsync, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) - { - var value = await cache.GetStringAsync(key, cToken); - if(value is null) - { - // create new and save - value = await factoryAsync(); - - Task CacheAsync() => options is null - ? cache.SetStringAsync(key: key, value: value, token: cToken) - : cache.SetStringAsync(key: key, value: value, options: options, token: cToken); - - if (cacheInBackground) - _ = Task.Run(async () => await CacheAsync(), cToken); - else - await CacheAsync(); - } - - return value; + Task CacheAsync() => options is null + ? cache.SetStringAsync(key: key, value: value, token: cToken) + : cache.SetStringAsync(key: key, value: value, options: options, token: cToken); + + if (cacheInBackground) + _ = Task.Run(async () => await CacheAsync(), cToken); + else + await CacheAsync(); } - #endregion - #region DateTime - public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func factory, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) + return value; + } + #endregion + + #region DateTime + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func factory, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) + { + if (await cache.GetDateTimeAsync(key, cToken) is DateTime dateTimeValue) + return dateTimeValue; + else { - if (await cache.GetDateTimeAsync(key, cToken) is DateTime dateTimeValue) - return dateTimeValue; - else - { - // create new and save - var newValue = factory(); + // create new and save + var newValue = factory(); - Task CacheAsync() => options is null - ? cache.SetDateTimeAsync(key, newValue, cToken: cToken) - : cache.SetDateTimeAsync(key, newValue, options, cToken); + Task CacheAsync() => options is null + ? cache.SetDateTimeAsync(key, newValue, cToken: cToken) + : cache.SetDateTimeAsync(key, newValue, options, cToken); - if (cacheInBackground) - _ = Task.Run(async () => await CacheAsync(), cToken); - else - await CacheAsync(); + if (cacheInBackground) + _ = Task.Run(async () => await CacheAsync(), cToken); + else + await CacheAsync(); - return newValue; - } + return newValue; } + } - public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func> factory, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static async Task GetOrSetAsync(this IDistributedCache cache, string key, Func> factory, DistributedCacheEntryOptions? options = null, bool cacheInBackground = false, CancellationToken cToken = default) + { + if (await cache.GetDateTimeAsync(key, cToken) is DateTime dateTimeValue) + return dateTimeValue; + else { - if (await cache.GetDateTimeAsync(key, cToken) is DateTime dateTimeValue) - return dateTimeValue; - else - { - // create new and save - var newValue = await factory(); + // create new and save + var newValue = await factory(); - Task CacheAsync() => options is null - ? cache.SetDateTimeAsync(key, newValue, cToken: cToken) - : cache.SetDateTimeAsync(key, newValue, options, cToken); + Task CacheAsync() => options is null + ? cache.SetDateTimeAsync(key, newValue, cToken: cToken) + : cache.SetDateTimeAsync(key, newValue, options, cToken); - if (cacheInBackground) - _ = Task.Run(async () => await CacheAsync(), cToken); - else - await CacheAsync(); + if (cacheInBackground) + _ = Task.Run(async () => await CacheAsync(), cToken); + else + await CacheAsync(); - return newValue; - } + return newValue; } - #endregion - - #endregion } + #endregion + + #endregion } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Extensions/MappingExtensions.cs b/EnvelopeGenerator.Application/Extensions/MappingExtensions.cs index 3a8a65f7..d2bde296 100644 --- a/EnvelopeGenerator.Application/Extensions/MappingExtensions.cs +++ b/EnvelopeGenerator.Application/Extensions/MappingExtensions.cs @@ -1,14 +1,27 @@ using EnvelopeGenerator.Application.DTOs.Messaging; -namespace EnvelopeGenerator.Application.Extensions +namespace EnvelopeGenerator.Application.Extensions; + +/// +/// Provides extension methods for common mapping and conversion operations. +/// +public static class MappingExtensions { - public static class MappingExtensions - { - public static bool Ok(this GtxMessagingResponse gtxMessagingResponse) - => gtxMessagingResponse.TryGetValue("message-status", out var status) - && status?.ToString()?.ToLower() == "ok"; + /// + /// Determines whether the response indicates a successful "OK" message status. + /// + /// The response object to evaluate. + /// if the response contains a "message-status" key with a value of "ok" (case-insensitive); + /// otherwise, . + public static bool Ok(this GtxMessagingResponse gtxMessagingResponse) + => gtxMessagingResponse.TryGetValue("message-status", out var status) + && status?.ToString()?.ToLower() == "ok"; - public static string ToBase64String(this byte[] bytes) - => Convert.ToBase64String(bytes); - } + /// + /// Converts the specified byte array to its equivalent string representation encoded in base-64. + /// + /// The byte array to encode. + /// A base-64 encoded string representation of the input byte array. + public static string ToBase64String(this byte[] bytes) + => Convert.ToBase64String(bytes); } \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryQueryHandler.cs b/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryQueryHandler.cs index 95c650d5..91354492 100644 --- a/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryQueryHandler.cs +++ b/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryQueryHandler.cs @@ -10,6 +10,7 @@ namespace EnvelopeGenerator.Application.Histories.Queries.Read; /// public class ReadHistoryQueryHandler : IRequestHandler> { + [Obsolete("Use IRepository")] private readonly IEnvelopeHistoryRepository _repository; private readonly IMapper _mapper; @@ -19,6 +20,7 @@ public class ReadHistoryQueryHandler : IRequestHandler /// /// + [Obsolete("Use IRepository")] public ReadHistoryQueryHandler(IEnvelopeHistoryRepository repository, IMapper mapper) { _repository = repository; @@ -41,4 +43,4 @@ public class ReadHistoryQueryHandler : IRequestHandler>(hists); } -} +} \ No newline at end of file diff --git a/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryResponse.cs b/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryResponse.cs index 3c0cd725..7957839b 100644 --- a/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryResponse.cs +++ b/EnvelopeGenerator.Application/Histories/Queries/Read/ReadHistoryResponse.cs @@ -20,7 +20,7 @@ public class ReadHistoryResponse /// /// Gets or sets the reference identifier of the user who performed the action. /// - public string UserReference { get; set; } + public required string UserReference { get; set; } /// /// Gets or sets the status code of the envelope.