Refactor email handling for improved structure

Refactored `Email` and `SendingEmailEvent` to use `record` types, consolidating email-related data into the `Email` class. Updated `SendEmailCommand` to return a `Guid` and simplified mapping logic in `EmailMappingProfile`. Adjusted `SendEmailCommandHandler` to construct `SendingEmailEvent` manually.

Updated `SendingEmailConsumer`, `EmailsController`, and `EmailSender` to reflect the new structure. Removed the old `Email` implementation. Improved logging to reference the `Mail` property.

Revised tests to align with the new structure, ensuring immutability and better separation of concerns.
This commit is contained in:
2026-08-05 13:59:54 +02:00
parent 66afdefbd8
commit c6e67c0f99
11 changed files with 128 additions and 110 deletions

View File

@@ -23,11 +23,11 @@ public class EmailsController(IMediator mediator) : ControllerBase
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> SendEmail([FromBody] SendEmailCommand command, CancellationToken cancellationToken)
{
var sendingEmailEvent = await mediator.Send(command, cancellationToken);
var eventId = await mediator.Send(command, cancellationToken);
return Accepted(new
{
sendingEmailEvent.Id,
Id = eventId
});
}
}

View File

@@ -1,46 +0,0 @@
using DigitalData.MessagingService.Abstraction;
namespace DigitalData.MessagingService.Client;
/// <summary>
/// Represents an outgoing email message to be sent through the messaging service.
/// </summary>
public record Email
{
/// <summary>
/// Recipient email address
/// </summary>
public IEnumerable<string> Recipients { get; set; } = null!;
/// <summary>
/// Email subject
/// </summary>
public string Subject { get; set; } = null!;
/// <summary>
/// Email body (HTML or plain text)
/// </summary>
public string Body { get; set; } = null!;
/// <summary>
/// Is HTML email (default: true)
/// </summary>
public bool IsHtml { get; set; } = true;
/// <summary>
/// Converts this <see cref="Email"/> instance to an <see cref="SendingEmailEvent"/>.
/// </summary>
/// <returns>A new <see cref="SendingEmailEvent"/> representing this email.</returns>
internal SendingEmailEvent ToEvent()
{
return new SendingEmailEvent
{
Id = Guid.NewGuid(),
Recipients = Recipients,
Subject = Subject,
Body = Body,
IsHtml = IsHtml,
QueuedAt = DateTime.Now
};
}
}

View File

@@ -125,6 +125,11 @@ public static class EmailSender
throw new InvalidOperationException("Messaging service is not connected. Call ConnectRabbitMq first.");
var publisher = LazyProvider.Value.GetRequiredService<ISendingEmailPublisher>();
publisher.EnqueueAsync(email.ToEvent());
publisher.EnqueueAsync(new SendingEmailEvent()
{
Id = Guid.NewGuid(),
Mail = email,
QueuedAt = DateTime.Now
});
}
}