diff --git a/src/BuildingBlocks/Core/Event/EventType.cs b/src/BuildingBlocks/Core/Event/EventType.cs index 1ec808c..9c0de49 100644 --- a/src/BuildingBlocks/Core/Event/EventType.cs +++ b/src/BuildingBlocks/Core/Event/EventType.cs @@ -4,5 +4,5 @@ namespace BuildingBlocks.Core.Event; public enum EventType { IntegrationEvent = 1, - DomainEvent = 2, + DomainEvent = 2 } diff --git a/src/BuildingBlocks/Core/Event/IDomainEvent.cs b/src/BuildingBlocks/Core/Event/IDomainEvent.cs index 3f3afed..65bc80d 100644 --- a/src/BuildingBlocks/Core/Event/IDomainEvent.cs +++ b/src/BuildingBlocks/Core/Event/IDomainEvent.cs @@ -2,5 +2,4 @@ namespace BuildingBlocks.Core.Event; public interface IDomainEvent : IEvent { - } diff --git a/src/BuildingBlocks/Core/EventDispatcher.cs b/src/BuildingBlocks/Core/EventDispatcher.cs index fb23629..b41f3cb 100644 --- a/src/BuildingBlocks/Core/EventDispatcher.cs +++ b/src/BuildingBlocks/Core/EventDispatcher.cs @@ -30,36 +30,43 @@ public sealed class EventDispatcher : IEventDispatcher _httpContextAccessor = httpContextAccessor; } - public async Task SendAsync(IDomainEvent domainEvent, - CancellationToken cancellationToken = default) => await SendAsync(new[] {domainEvent}, cancellationToken); - public async Task SendAsync(IReadOnlyList domainEvents, CancellationToken cancellationToken = default) + public async Task SendAsync(IReadOnlyList events, CancellationToken cancellationToken = default) + where T : IEvent { - if (domainEvents is null) return; - - var integrationEvents = await MapDomainEventToIntegrationEventAsync(domainEvents).ConfigureAwait(false); - - if (integrationEvents.Count == 0) return; - - foreach (var integrationEvent in integrationEvents) + async Task PublishIntegrationEvent(IReadOnlyList integrationEvents) { - await _persistMessageProcessor.PublishMessageAsync(new MessageEnvelope(integrationEvent, SetHeaders()), - cancellationToken); + foreach (var integrationEvent in integrationEvents) + { + await _persistMessageProcessor.PublishMessageAsync(new MessageEnvelope(integrationEvent, SetHeaders()), + cancellationToken); + } + } + + if (events.Count > 0) + { + switch (events) + { + case IReadOnlyList domainEvents: + { + var integrationEvents = await MapDomainEventToIntegrationEventAsync(domainEvents) + .ConfigureAwait(false); + + await PublishIntegrationEvent(integrationEvents); + break; + } + + case IReadOnlyList integrationEvents: + await PublishIntegrationEvent(integrationEvents); + break; + } } } + public async Task SendAsync(T @event, CancellationToken cancellationToken = default) + where T : IEvent => + await SendAsync(new[] {@event}, cancellationToken); - public async Task SendAsync(IIntegrationEvent integrationEvent, - CancellationToken cancellationToken = default) => await SendAsync(new[] {integrationEvent}, cancellationToken); - - public async Task SendAsync(IReadOnlyList integrationEvents, - CancellationToken cancellationToken = default) - { - if (integrationEvents is null) return; - - await _persistMessageProcessor.PublishMessageAsync(new MessageEnvelope(integrationEvents, SetHeaders()), - cancellationToken); - } private Task> MapDomainEventToIntegrationEventAsync( IReadOnlyList events) diff --git a/src/BuildingBlocks/Core/IEventDispatcher.cs b/src/BuildingBlocks/Core/IEventDispatcher.cs index 348fd10..44a4f94 100644 --- a/src/BuildingBlocks/Core/IEventDispatcher.cs +++ b/src/BuildingBlocks/Core/IEventDispatcher.cs @@ -4,9 +4,8 @@ namespace BuildingBlocks.Core; public interface IEventDispatcher { - public Task SendAsync(IReadOnlyList domainEvents, CancellationToken cancellationToken = default); - public Task SendAsync(IDomainEvent domainEvent, CancellationToken cancellationToken = default); - - public Task SendAsync(IIntegrationEvent integrationEvent, CancellationToken cancellationToken = default); - public Task SendAsync(IReadOnlyList integrationEvents, CancellationToken cancellationToken = default); + public Task SendAsync(IReadOnlyList events, CancellationToken cancellationToken = default) + where T : IEvent; + public Task SendAsync(T @event, CancellationToken cancellationToken = default) + where T : IEvent; } diff --git a/src/BuildingBlocks/EFCore/EfTxBehavior.cs b/src/BuildingBlocks/EFCore/EfTxBehavior.cs index 4a84a39..5226651 100644 --- a/src/BuildingBlocks/EFCore/EfTxBehavior.cs +++ b/src/BuildingBlocks/EFCore/EfTxBehavior.cs @@ -1,6 +1,7 @@ using System.Data; using System.Text.Json; using BuildingBlocks.Core; +using BuildingBlocks.Core.Event; using MediatR; using Microsoft.Extensions.Logging; diff --git a/src/Services/Flight/src/Flight/Flights/Features/CreateFlight/Reads/CreateFlightMongoCommandHandler.cs b/src/Services/Flight/src/Flight/Flights/Features/CreateFlight/Reads/CreateFlightMongoCommandHandler.cs index aa92e58..e48549f 100644 --- a/src/Services/Flight/src/Flight/Flights/Features/CreateFlight/Reads/CreateFlightMongoCommandHandler.cs +++ b/src/Services/Flight/src/Flight/Flights/Features/CreateFlight/Reads/CreateFlightMongoCommandHandler.cs @@ -1,11 +1,15 @@ -using System.Threading; +using System.Linq; +using System.Threading; using System.Threading.Tasks; using Ardalis.GuardClauses; using BuildingBlocks.Core.CQRS; using Flight.Data; +using Flight.Flights.Exceptions; using Flight.Flights.Models.Reads; using MapsterMapper; using MediatR; +using MongoDB.Driver; +using MongoDB.Driver.Linq; namespace Flight.Flights.Features.CreateFlight.Reads; @@ -28,6 +32,12 @@ public class CreateFlightMongoCommandHandler : ICommandHandler(command); + var flight = await _flightReadDbContext.Flight.AsQueryable() + .FirstOrDefaultAsync(x => x.Id == command.Id, cancellationToken); + + if (flight is not null) + throw new FlightAlreadyExistException(); + await _flightReadDbContext.Flight.InsertOneAsync(flightReadModel, cancellationToken: cancellationToken); return Unit.Value;