diff --git a/src/Services/Ordering/Ordering.API/Application/EventHandlers/OrderCreatedEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCreatedDomainEventHandler.cs similarity index 74% rename from src/Services/Ordering/Ordering.API/Application/EventHandlers/OrderCreatedEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCreatedDomainEventHandler.cs index 422a61c9b..8aed7f1b2 100644 --- a/src/Services/Ordering/Ordering.API/Application/EventHandlers/OrderCreatedEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCreatedDomainEventHandler.cs @@ -6,22 +6,22 @@ using Ordering.Domain.Events; using System; using System.Threading.Tasks; -namespace Ordering.API.Application.EventHandlers +namespace Ordering.API.Application.DomainEventHandlers { - public class OrderCreatedEventHandler : IAsyncNotificationHandler + public class OrderCreatedDomainEventHandler : IAsyncNotificationHandler { private readonly ILoggerFactory _logger; private readonly IBuyerRepository _buyerRepository; private readonly IIdentityService _identityService; - public OrderCreatedEventHandler(ILoggerFactory logger, IBuyerRepository buyerRepository, IIdentityService identityService) + public OrderCreatedDomainEventHandler(ILoggerFactory logger, IBuyerRepository buyerRepository, IIdentityService identityService) { _buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository)); _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public async Task Handle(OrderCreated orderNotification) + public async Task Handle(OrderCreatedDomainEvent orderNotification) { var cardTypeId = orderNotification.CardTypeId != 0 ? orderNotification.CardTypeId : 1; @@ -46,7 +46,7 @@ namespace Ordering.API.Application.EventHandlers await _buyerRepository.UnitOfWork .SaveEntitiesAsync(); - _logger.CreateLogger(nameof(OrderCreatedEventHandler)).LogTrace($"A new payment method has been successfully added for orderId: {orderNotification.Order.Id}."); + _logger.CreateLogger(nameof(OrderCreatedDomainEventHandler)).LogTrace($"A new payment method has been successfully added for orderId: {orderNotification.Order.Id}."); } } diff --git a/src/Services/Ordering/Ordering.API/Application/EventHandlers/PaymentMethodCheckedEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/PaymentMethodCheckedDomainEventHandler.cs similarity index 71% rename from src/Services/Ordering/Ordering.API/Application/EventHandlers/PaymentMethodCheckedEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/PaymentMethodCheckedDomainEventHandler.cs index b72b89363..eb833f70e 100644 --- a/src/Services/Ordering/Ordering.API/Application/EventHandlers/PaymentMethodCheckedEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/PaymentMethodCheckedDomainEventHandler.cs @@ -5,19 +5,19 @@ using Ordering.Domain.Events; using System; using System.Threading.Tasks; -namespace Ordering.API.Application.EventHandlers +namespace Ordering.API.Application.DomainEventHandlers { - public class PaymentMethodCheckedEventHandler : IAsyncNotificationHandler + public class PaymentMethodCheckedDomainEventHandler : IAsyncNotificationHandler { private readonly IOrderRepository _orderRepository; private readonly ILoggerFactory _logger; - public PaymentMethodCheckedEventHandler(IOrderRepository orderRepository, ILoggerFactory logger) + public PaymentMethodCheckedDomainEventHandler(IOrderRepository orderRepository, ILoggerFactory logger) { _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public async Task Handle(PaymentMethodChecked paymentMethodNotification) + public async Task Handle(PaymentMethodCheckedDomainEvent paymentMethodNotification) { var orderToUpdate = await _orderRepository.GetAsync(paymentMethodNotification.OrderId); orderToUpdate.SetBuyerId(paymentMethodNotification.Buyer.Id); @@ -26,7 +26,7 @@ namespace Ordering.API.Application.EventHandlers await _orderRepository.UnitOfWork .SaveEntitiesAsync(); - _logger.CreateLogger(nameof(PaymentMethodCheckedEventHandler)) + _logger.CreateLogger(nameof(PaymentMethodCheckedDomainEventHandler)) .LogTrace($"Order with Id: {paymentMethodNotification.OrderId} has been successfully updated with a new payment method id: { paymentMethodNotification.Payment.Id }"); } } diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs index 8585b8aa9..8d76fd9f5 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs @@ -3,7 +3,7 @@ using Autofac.Core; using MediatR; using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Decorators; -using Ordering.API.Application.EventHandlers; +using Ordering.API.Application.DomainEventHandlers; using Ordering.Domain.Events; using System.Collections.Generic; using System.Linq; @@ -24,7 +24,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Autof .Select(i => new KeyedService("IAsyncRequestHandler", i))); builder - .RegisterAssemblyTypes(typeof(OrderCreatedEventHandler).GetTypeInfo().Assembly) + .RegisterAssemblyTypes(typeof(OrderCreatedDomainEventHandler).GetTypeInfo().Assembly) .Where(t => t.IsClosedTypeOf(typeof(IAsyncNotificationHandler<>))) .AsImplementedInterfaces(); diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs index 64acbf7b7..cedb42c06 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs @@ -33,7 +33,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B if (existingPayment != null) { - AddEvent(new PaymentMethodChecked(this, existingPayment, orderId)); + AddDomainEvent(new PaymentMethodCheckedDomainEvent(this, existingPayment, orderId)); return existingPayment; } else @@ -41,7 +41,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B var payment = new PaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration); _paymentMethods.Add(payment); - AddEvent(new PaymentMethodChecked(this, payment, orderId)); + AddDomainEvent(new PaymentMethodCheckedDomainEvent(this, payment, orderId)); return payment; } } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs index a1bb76cee..6ccece658 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs @@ -51,7 +51,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O _orderStatusId = OrderStatus.InProcess.Id; _orderDate = DateTime.UtcNow; Address = address; - AddCreatedOrderEvent(cardTypeId, cardNumber, + + // Add the OrderCreatedEvent to the domain events collection + // to be raised/dispatched when comitting changes into the Database [ After DbContext.SaveChanges() ] + AddOrderCreatedDomainEvent(cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); } @@ -93,14 +96,14 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O _buyerId = id; } - private void AddCreatedOrderEvent(int cardTypeId, string cardNumber, + private void AddOrderCreatedDomainEvent(int cardTypeId, string cardNumber, string cardSecurityNumber, string cardHolderName, DateTime cardExpiration) { - var @orderCreatedEvent = new OrderCreated( + var orderCreatedDomainEvent = new OrderCreatedDomainEvent( this, cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); - AddEvent(@orderCreatedEvent); + AddDomainEvent(orderCreatedDomainEvent); } } } diff --git a/src/Services/Ordering/Ordering.Domain/Events/OrderCreated.cs b/src/Services/Ordering/Ordering.Domain/Events/OrderCreatedDomainEvent.cs similarity index 92% rename from src/Services/Ordering/Ordering.Domain/Events/OrderCreated.cs rename to src/Services/Ordering/Ordering.Domain/Events/OrderCreatedDomainEvent.cs index 489cc23d0..04fdb41db 100644 --- a/src/Services/Ordering/Ordering.Domain/Events/OrderCreated.cs +++ b/src/Services/Ordering/Ordering.Domain/Events/OrderCreatedDomainEvent.cs @@ -9,7 +9,7 @@ namespace Ordering.Domain.Events /// /// Event used when an order is created /// - public class OrderCreated + public class OrderCreatedDomainEvent : IAsyncNotification { public int CardTypeId { get; private set; } @@ -19,7 +19,7 @@ namespace Ordering.Domain.Events public DateTime CardExpiration { get; private set; } public Order Order { get; private set; } - public OrderCreated(Order order, + public OrderCreatedDomainEvent(Order order, int cardTypeId, string cardNumber, string cardSecurityNumber, string cardHolderName, DateTime cardExpiration) diff --git a/src/Services/Ordering/Ordering.Domain/Events/PaymentMethodChecked.cs b/src/Services/Ordering/Ordering.Domain/Events/PaymentMethodCheckedDomainEvent.cs similarity index 78% rename from src/Services/Ordering/Ordering.Domain/Events/PaymentMethodChecked.cs rename to src/Services/Ordering/Ordering.Domain/Events/PaymentMethodCheckedDomainEvent.cs index 25c8d8111..a729361c7 100644 --- a/src/Services/Ordering/Ordering.Domain/Events/PaymentMethodChecked.cs +++ b/src/Services/Ordering/Ordering.Domain/Events/PaymentMethodCheckedDomainEvent.cs @@ -6,14 +6,14 @@ using System.Text; namespace Ordering.Domain.Events { - public class PaymentMethodChecked + public class PaymentMethodCheckedDomainEvent : IAsyncNotification { public Buyer Buyer { get; private set; } public PaymentMethod Payment { get; private set; } public int OrderId { get; private set; } - public PaymentMethodChecked(Buyer buyer, PaymentMethod payment, int orderId) + public PaymentMethodCheckedDomainEvent(Buyer buyer, PaymentMethod payment, int orderId) { Buyer = buyer; Payment = payment; diff --git a/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs b/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs index e2c602300..7616a3230 100644 --- a/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs +++ b/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs @@ -10,7 +10,7 @@ int? _requestedHashCode; int _Id; - private List _events; + private List _domainEvents; public virtual int Id { @@ -24,17 +24,17 @@ } } - public List Events => _events; - public void AddEvent(IAsyncNotification eventItem) + public List DomainEvents => _domainEvents; + public void AddDomainEvent(IAsyncNotification eventItem) { - _events = _events ?? new List(); - _events.Add(eventItem); + _domainEvents = _domainEvents ?? new List(); + _domainEvents.Add(eventItem); } - public void RemoveEvent(IAsyncNotification eventItem) + public void RemoveDomainEvent(IAsyncNotification eventItem) { - if (_events is null) return; - _events.Remove(eventItem); + if (_domainEvents is null) return; + _domainEvents.Remove(eventItem); } public bool IsTransient() diff --git a/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs b/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs index 5949f00b4..21fc5e21f 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs @@ -10,9 +10,9 @@ namespace Ordering.Infrastructure { public static async Task RaiseDomainEventsAsync(this IMediator mediator, OrderingContext ctx) { - var domainEntities = ctx.ChangeTracker.Entries().Where(x => x.Entity.Events != null && x.Entity.Events.Any()); - var domainEvents = domainEntities.SelectMany(x => x.Entity.Events).ToList(); - domainEntities.ToList().ForEach(entity => entity.Entity.Events.Clear()); + var domainEntities = ctx.ChangeTracker.Entries().Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any()); + var domainEvents = domainEntities.SelectMany(x => x.Entity.DomainEvents).ToList(); + domainEntities.ToList().ForEach(entity => entity.Entity.DomainEvents.Clear()); var tasks = domainEvents .Select(async (domainEvent) => { diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs index 504ed0ab7..56790185e 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs @@ -74,7 +74,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure buyerConfiguration.HasKey(b => b.Id); - buyerConfiguration.Ignore(b => b.Events); + buyerConfiguration.Ignore(b => b.DomainEvents); buyerConfiguration.Property(b => b.Id) .ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA); @@ -102,7 +102,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure paymentConfiguration.HasKey(b => b.Id); - paymentConfiguration.Ignore(b => b.Events); + paymentConfiguration.Ignore(b => b.DomainEvents); paymentConfiguration.Property(b => b.Id) .ForSqlServerUseSequenceHiLo("paymentseq", DEFAULT_SCHEMA); @@ -139,7 +139,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure orderConfiguration.HasKey(o => o.Id); - orderConfiguration.Ignore(b => b.Events); + orderConfiguration.Ignore(b => b.DomainEvents); orderConfiguration.Property(o => o.Id) .ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA); @@ -176,7 +176,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure orderItemConfiguration.HasKey(o => o.Id); - orderItemConfiguration.Ignore(b => b.Events); + orderItemConfiguration.Ignore(b => b.DomainEvents); orderItemConfiguration.Property(o => o.Id) .ForSqlServerUseSequenceHiLo("orderitemseq"); @@ -238,6 +238,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)) { var result = await base.SaveChangesAsync(); + + // Dispatch the Domain Events collection right after saving/commiting data into the database await _mediator.RaiseDomainEventsAsync(this); return result; } diff --git a/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs b/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs index 2cf035205..0703ed197 100644 --- a/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs +++ b/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs @@ -122,6 +122,6 @@ public class BuyerAggregateTest fakeBuyer.AddPaymentMethod(cardTypeId, alias, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration, orderId); //Assert - Assert.Equal(fakeBuyer.Events.Count, expectedResult); + Assert.Equal(fakeBuyer.DomainEvents.Count, expectedResult); } } \ No newline at end of file diff --git a/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs b/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs index dab34f528..c420951da 100644 --- a/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs +++ b/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs @@ -112,7 +112,7 @@ public class OrderAggregateTest var fakeOrder = new Order(new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); //Assert - Assert.Equal(fakeOrder.Events.Count, expectedResult); + Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); } [Fact] @@ -133,9 +133,9 @@ public class OrderAggregateTest //Act var fakeOrder = new Order(new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); - fakeOrder.AddEvent(new OrderCreated(fakeOrder,cardTypeId,cardNumber,cardSecurityNumber,cardHolderName,cardExpiration)); + fakeOrder.AddDomainEvent(new OrderCreatedDomainEvent(fakeOrder,cardTypeId,cardNumber,cardSecurityNumber,cardHolderName,cardExpiration)); //Assert - Assert.Equal(fakeOrder.Events.Count, expectedResult); + Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); } [Fact] @@ -153,13 +153,13 @@ public class OrderAggregateTest var cardHolderName = "FakeName"; var cardExpiration = DateTime.Now.AddYears(1); var fakeOrder = new Order(new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); - var @fakeEvent = new OrderCreated(fakeOrder, cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); + var @fakeEvent = new OrderCreatedDomainEvent(fakeOrder, cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); var expectedResult = 1; //Act - fakeOrder.AddEvent(@fakeEvent); - fakeOrder.RemoveEvent(@fakeEvent); + fakeOrder.AddDomainEvent(@fakeEvent); + fakeOrder.RemoveDomainEvent(@fakeEvent); //Assert - Assert.Equal(fakeOrder.Events.Count, expectedResult); + Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); } } \ No newline at end of file