From e73bead2f2117a8eb2221ea5b89a79a14a34fbc1 Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 13 Aug 2026 13:11:18 +0200 Subject: [PATCH] Refactor email fetching to use IMailRepository Introduced a new `IMailRepository` interface to abstract email-fetching logic, replacing the direct dependency on `IImapEmailService` in `ReadEmailQueryHandler`. Updated `ReadEmailQueryHandler` to use `IMailRepository` for querying emails and added `IMapper` for mapping entities to DTOs. Modified the constructor of `ReadEmailQueryHandler` to inject `IMailRepository`, `IMapper`, and renamed `IRepository` to `EmailAccountRepo`. Replaced `IImapEmailService.FetchEmailsAsync` with `IMailRepository.FindAsync` in the handler's `Handle` method. Wrapped all changes in `#if NET` preprocessor directives to ensure compatibility with specific build configurations. These changes improve modularity, testability, and separation of concerns. --- .../Interfaces/Repositories/IMailRepository.cs | 11 +++++++++++ .../EmailReceiving/Queries/ReadEmailQuery.cs | 13 ++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 src/core/DigitalData.MessagingService.Application/Common/Interfaces/Repositories/IMailRepository.cs diff --git a/src/core/DigitalData.MessagingService.Application/Common/Interfaces/Repositories/IMailRepository.cs b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/Repositories/IMailRepository.cs new file mode 100644 index 0000000..1e8467f --- /dev/null +++ b/src/core/DigitalData.MessagingService.Application/Common/Interfaces/Repositories/IMailRepository.cs @@ -0,0 +1,11 @@ +#if NET +using DigitalData.MessagingService.Application.Common.Dto.MailSearch; +using DigitalData.MessagingService.Domain.Entities; + +namespace DigitalData.MessagingService.Application.Common.Interfaces.Repositories; + +public interface IMailRepository : IRepository +{ + public Task> FindAsync(MailSearchFilter mailSearchFilter, EmailAccount accountQuery, CancellationToken cancellationToken = default); +} +#endif \ No newline at end of file diff --git a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs index c1274e4..85a1d36 100644 --- a/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs +++ b/src/core/DigitalData.MessagingService.Application/EmailReceiving/Queries/ReadEmailQuery.cs @@ -1,4 +1,5 @@ #if NET +using AutoMapper; using DigitalData.MessagingService.Application.Common.Dto; using DigitalData.MessagingService.Application.Common.Dto.MailSearch; using DigitalData.MessagingService.Application.Common.Interfaces; @@ -27,26 +28,24 @@ public record ReadEmailQuery : IRequest> public MailSearchFilter Mail { get; init; } = new(); } -public class ReadEmailQueryHandler(IImapEmailService ImapService, ILogger Logger, IRepository Repo) : IRequestHandler> +public class ReadEmailQueryHandler(IMapper Mapper, ILogger Logger, IRepository EmailAccountRepo, IMailRepository MailRepo) : IRequestHandler> { public async Task> Handle(ReadEmailQuery request, CancellationToken cancellationToken) { - var accounts = await Repo.FindAsync(request.Account.Id is int id ? x => x.Id == id : x => x.Username == request.Account.Username, cancellationToken: cancellationToken); + var accounts = await EmailAccountRepo.FindAsync(request.Account.Id is int id ? x => x.Id == id : x => x.Username == request.Account.Username, cancellationToken: cancellationToken); if (accounts.Count() > 1) Logger.LogWarning("Multiple email accounts found for the given criteria ({Criteria}). Returning the first one.", request.Account.Id is not null ? $"Id: {request.Account.Id}" : $"Username: {request.Account.Username}"); - EmailAccount account = accounts.FirstOrDefault() + var account = accounts.FirstOrDefault() ?? throw new NotFoundException($"No email account found for the given criteria (Id: {request.Account.Id}, Username: {request.Account.Username})."); if (string.IsNullOrWhiteSpace(account.ImapServer)) throw new BadRequestException( $"IMAP is not configured for account '{account.Username}' (Id: {account.Id}). Set ImapServer in EmailAccounts configuration."); - return await ImapService.FetchEmailsAsync( - account, - request.Mail, - cancellationToken); + var mails = await MailRepo.FindAsync(request.Mail, account, cancellationToken); + return Mapper.Map>(mails); } } #endif \ No newline at end of file