From c7e317413ebba3cdec6633c4996a2d0e0feec778 Mon Sep 17 00:00:00 2001 From: Cesar De la Torre Date: Fri, 17 Mar 2017 18:36:34 -0700 Subject: [PATCH] Refactoring Domain Events --- ...PaymentMethodVerifiedDomainEventHandler.cs | 36 +++++++++++++++++++ ...r.cs => OrderStartedDomainEventHandler.cs} | 10 +++--- .../PaymentMethodCheckedDomainEventHandler.cs | 33 ----------------- .../AutofacModules/MediatorModule.cs | 2 +- .../AggregatesModel/BuyerAggregate/Buyer.cs | 6 ++-- .../AggregatesModel/OrderAggregate/Order.cs | 12 +++---- ... BuyerPaymentMethodVerifiedDomainEvent.cs} | 4 +-- ...ainEvent.cs => OrderStartedDomainEvent.cs} | 4 +-- .../MediatorExtension.cs | 2 +- .../OrderingContext.cs | 4 +-- .../Ordering/Domain/BuyerAggregateTest.cs | 4 +-- .../Ordering/Domain/OrderAggregateTest.cs | 4 +-- 12 files changed, 62 insertions(+), 59 deletions(-) create mode 100644 src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerPaymentMethodVerifiedDomainEventHandler.cs rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderCreatedDomainEventHandler.cs => OrderStartedDomainEventHandler.cs} (83%) delete mode 100644 src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/PaymentMethodCheckedDomainEventHandler.cs rename src/Services/Ordering/Ordering.Domain/Events/{PaymentMethodCheckedDomainEvent.cs => BuyerPaymentMethodVerifiedDomainEvent.cs} (76%) rename src/Services/Ordering/Ordering.Domain/Events/{OrderCreatedDomainEvent.cs => OrderStartedDomainEvent.cs} (92%) diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerPaymentMethodVerifiedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerPaymentMethodVerifiedDomainEventHandler.cs new file mode 100644 index 000000000..70360ce32 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerPaymentMethodVerifiedDomainEventHandler.cs @@ -0,0 +1,36 @@ +using MediatR; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Microsoft.Extensions.Logging; +using Ordering.Domain.Events; +using System; +using System.Threading.Tasks; + +namespace Ordering.API.Application.DomainEventHandlers +{ + public class BuyerPaymentMethodVerifiedDomainEventHandler : IAsyncNotificationHandler + { + private readonly IOrderRepository _orderRepository; + private readonly ILoggerFactory _logger; + public BuyerPaymentMethodVerifiedDomainEventHandler(IOrderRepository orderRepository, ILoggerFactory logger) + { + _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + // Domain Logic comment: + // When the Buyer and Buyer's payment method have been created or verified that they existed, + // then we can update the original Order with the BuyerId and PaymentId (foreign keys) + public async Task Handle(BuyerPaymentMethodVerifiedDomainEvent buyerPaymentMethodVerifiedEvent) + { + var orderToUpdate = await _orderRepository.GetAsync(buyerPaymentMethodVerifiedEvent.OrderId); + orderToUpdate.SetBuyerId(buyerPaymentMethodVerifiedEvent.Buyer.Id); + orderToUpdate.SetPaymentId(buyerPaymentMethodVerifiedEvent.Payment.Id); + + await _orderRepository.UnitOfWork + .SaveEntitiesAsync(); + + _logger.CreateLogger(nameof(BuyerPaymentMethodVerifiedDomainEventHandler)) + .LogTrace($"Order with Id: {buyerPaymentMethodVerifiedEvent.OrderId} has been successfully updated with a payment method id: { buyerPaymentMethodVerifiedEvent.Payment.Id }"); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCreatedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedDomainEventHandler.cs similarity index 83% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCreatedDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedDomainEventHandler.cs index 8aed7f1b2..249976f0c 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCreatedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedDomainEventHandler.cs @@ -8,20 +8,20 @@ using System.Threading.Tasks; namespace Ordering.API.Application.DomainEventHandlers { - public class OrderCreatedDomainEventHandler : IAsyncNotificationHandler + public class OrderStartedDomainEventHandler : IAsyncNotificationHandler { private readonly ILoggerFactory _logger; private readonly IBuyerRepository _buyerRepository; private readonly IIdentityService _identityService; - public OrderCreatedDomainEventHandler(ILoggerFactory logger, IBuyerRepository buyerRepository, IIdentityService identityService) + public OrderStartedDomainEventHandler(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(OrderCreatedDomainEvent orderNotification) + public async Task Handle(OrderStartedDomainEvent orderNotification) { var cardTypeId = orderNotification.CardTypeId != 0 ? orderNotification.CardTypeId : 1; @@ -33,7 +33,7 @@ namespace Ordering.API.Application.DomainEventHandlers buyer = new Buyer(buyerGuid); } - var payment = buyer.AddPaymentMethod(cardTypeId, + var paymentMethod = buyer.VerifyOrAddPaymentMethod(cardTypeId, $"Payment Method on {DateTime.UtcNow}", orderNotification.CardNumber, orderNotification.CardSecurityNumber, @@ -46,7 +46,7 @@ namespace Ordering.API.Application.DomainEventHandlers await _buyerRepository.UnitOfWork .SaveEntitiesAsync(); - _logger.CreateLogger(nameof(OrderCreatedDomainEventHandler)).LogTrace($"A new payment method has been successfully added for orderId: {orderNotification.Order.Id}."); + _logger.CreateLogger(nameof(OrderStartedDomainEventHandler)).LogTrace($"A new payment method has been successfully added for orderId: {orderNotification.Order.Id}."); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/PaymentMethodCheckedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/PaymentMethodCheckedDomainEventHandler.cs deleted file mode 100644 index eb833f70e..000000000 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/PaymentMethodCheckedDomainEventHandler.cs +++ /dev/null @@ -1,33 +0,0 @@ -using MediatR; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; -using Microsoft.Extensions.Logging; -using Ordering.Domain.Events; -using System; -using System.Threading.Tasks; - -namespace Ordering.API.Application.DomainEventHandlers -{ - public class PaymentMethodCheckedDomainEventHandler : IAsyncNotificationHandler - { - private readonly IOrderRepository _orderRepository; - private readonly 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(PaymentMethodCheckedDomainEvent paymentMethodNotification) - { - var orderToUpdate = await _orderRepository.GetAsync(paymentMethodNotification.OrderId); - orderToUpdate.SetBuyerId(paymentMethodNotification.Buyer.Id); - orderToUpdate.SetPaymentId(paymentMethodNotification.Payment.Id); - - await _orderRepository.UnitOfWork - .SaveEntitiesAsync(); - - _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 8d76fd9f5..0f0f8b098 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs @@ -24,7 +24,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Autof .Select(i => new KeyedService("IAsyncRequestHandler", i))); builder - .RegisterAssemblyTypes(typeof(OrderCreatedDomainEventHandler).GetTypeInfo().Assembly) + .RegisterAssemblyTypes(typeof(OrderStartedDomainEventHandler).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 cedb42c06..689122189 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/Buyer.cs @@ -24,7 +24,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B IdentityGuid = !string.IsNullOrWhiteSpace(identity) ? identity : throw new ArgumentNullException(nameof(identity)); } - public PaymentMethod AddPaymentMethod( + public PaymentMethod VerifyOrAddPaymentMethod( int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration, int orderId) { @@ -33,7 +33,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.B if (existingPayment != null) { - AddDomainEvent(new PaymentMethodCheckedDomainEvent(this, existingPayment, orderId)); + AddDomainEvent(new BuyerPaymentMethodVerifiedDomainEvent(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); - AddDomainEvent(new PaymentMethodCheckedDomainEvent(this, payment, orderId)); + AddDomainEvent(new BuyerPaymentMethodVerifiedDomainEvent(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 6ccece658..a3df725dd 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs @@ -52,10 +52,10 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O _orderDate = DateTime.UtcNow; Address = address; - // Add the OrderCreatedEvent to the domain events collection + // Add the OrderStarterDomainEvent to the domain events collection // to be raised/dispatched when comitting changes into the Database [ After DbContext.SaveChanges() ] - AddOrderCreatedDomainEvent(cardTypeId, cardNumber, - cardSecurityNumber, cardHolderName, cardExpiration); + AddOrderStartedDomainEvent(cardTypeId, cardNumber, + cardSecurityNumber, cardHolderName, cardExpiration); } // DDD Patterns comment @@ -96,14 +96,14 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O _buyerId = id; } - private void AddOrderCreatedDomainEvent(int cardTypeId, string cardNumber, + private void AddOrderStartedDomainEvent(int cardTypeId, string cardNumber, string cardSecurityNumber, string cardHolderName, DateTime cardExpiration) { - var orderCreatedDomainEvent = new OrderCreatedDomainEvent( + var orderStartedDomainEvent = new OrderStartedDomainEvent( this, cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); - AddDomainEvent(orderCreatedDomainEvent); + this.AddDomainEvent(orderStartedDomainEvent); } } } diff --git a/src/Services/Ordering/Ordering.Domain/Events/PaymentMethodCheckedDomainEvent.cs b/src/Services/Ordering/Ordering.Domain/Events/BuyerPaymentMethodVerifiedDomainEvent.cs similarity index 76% rename from src/Services/Ordering/Ordering.Domain/Events/PaymentMethodCheckedDomainEvent.cs rename to src/Services/Ordering/Ordering.Domain/Events/BuyerPaymentMethodVerifiedDomainEvent.cs index a729361c7..3a3a00a0a 100644 --- a/src/Services/Ordering/Ordering.Domain/Events/PaymentMethodCheckedDomainEvent.cs +++ b/src/Services/Ordering/Ordering.Domain/Events/BuyerPaymentMethodVerifiedDomainEvent.cs @@ -6,14 +6,14 @@ using System.Text; namespace Ordering.Domain.Events { - public class PaymentMethodCheckedDomainEvent + public class BuyerPaymentMethodVerifiedDomainEvent : IAsyncNotification { public Buyer Buyer { get; private set; } public PaymentMethod Payment { get; private set; } public int OrderId { get; private set; } - public PaymentMethodCheckedDomainEvent(Buyer buyer, PaymentMethod payment, int orderId) + public BuyerPaymentMethodVerifiedDomainEvent(Buyer buyer, PaymentMethod payment, int orderId) { Buyer = buyer; Payment = payment; diff --git a/src/Services/Ordering/Ordering.Domain/Events/OrderCreatedDomainEvent.cs b/src/Services/Ordering/Ordering.Domain/Events/OrderStartedDomainEvent.cs similarity index 92% rename from src/Services/Ordering/Ordering.Domain/Events/OrderCreatedDomainEvent.cs rename to src/Services/Ordering/Ordering.Domain/Events/OrderStartedDomainEvent.cs index 04fdb41db..439a5d9ab 100644 --- a/src/Services/Ordering/Ordering.Domain/Events/OrderCreatedDomainEvent.cs +++ b/src/Services/Ordering/Ordering.Domain/Events/OrderStartedDomainEvent.cs @@ -9,7 +9,7 @@ namespace Ordering.Domain.Events /// /// Event used when an order is created /// - public class OrderCreatedDomainEvent + public class OrderStartedDomainEvent : 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 OrderCreatedDomainEvent(Order order, + public OrderStartedDomainEvent(Order order, int cardTypeId, string cardNumber, string cardSecurityNumber, string cardHolderName, DateTime cardExpiration) diff --git a/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs b/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs index 21fc5e21f..99e94e086 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/MediatorExtension.cs @@ -8,7 +8,7 @@ namespace Ordering.Infrastructure { public static class MediatorExtension { - public static async Task RaiseDomainEventsAsync(this IMediator mediator, OrderingContext ctx) + public static async Task DispatchDomainEventsAsync(this IMediator mediator, OrderingContext ctx) { var domainEntities = ctx.ChangeTracker.Entries().Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any()); var domainEvents = domainEntities.SelectMany(x => x.Entity.DomainEvents).ToList(); diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs index 56790185e..de3f870da 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs @@ -239,8 +239,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure { var result = await base.SaveChangesAsync(); - // Dispatch the Domain Events collection right after saving/commiting data into the database - await _mediator.RaiseDomainEventsAsync(this); + // Dispatch the Domain Events collection right after saving/committing data into the database + await _mediator.DispatchDomainEventsAsync(this); return result; } } diff --git a/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs b/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs index 0703ed197..32e3bb807 100644 --- a/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs +++ b/test/Services/UnitTest/Ordering/Domain/BuyerAggregateTest.cs @@ -45,7 +45,7 @@ public class BuyerAggregateTest var fakeBuyerItem = new Buyer(identity); //Act - var result = fakeBuyerItem.AddPaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration, orderId); + var result = fakeBuyerItem.VerifyOrAddPaymentMethod(cardTypeId, alias, cardNumber, securityNumber, cardHolderName, expiration, orderId); //Assert Assert.NotNull(result); @@ -119,7 +119,7 @@ public class BuyerAggregateTest //Act var fakeBuyer = new Buyer(Guid.NewGuid().ToString()); - fakeBuyer.AddPaymentMethod(cardTypeId, alias, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration, orderId); + fakeBuyer.VerifyOrAddPaymentMethod(cardTypeId, alias, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration, orderId); //Assert Assert.Equal(fakeBuyer.DomainEvents.Count, expectedResult); diff --git a/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs b/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs index c420951da..61fac6cf1 100644 --- a/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs +++ b/test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs @@ -133,7 +133,7 @@ public class OrderAggregateTest //Act var fakeOrder = new Order(new Address(street, city, state, country, zipcode), cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); - fakeOrder.AddDomainEvent(new OrderCreatedDomainEvent(fakeOrder,cardTypeId,cardNumber,cardSecurityNumber,cardHolderName,cardExpiration)); + fakeOrder.AddDomainEvent(new OrderStartedDomainEvent(fakeOrder,cardTypeId,cardNumber,cardSecurityNumber,cardHolderName,cardExpiration)); //Assert Assert.Equal(fakeOrder.DomainEvents.Count, expectedResult); } @@ -153,7 +153,7 @@ 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 OrderCreatedDomainEvent(fakeOrder, cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); + var @fakeEvent = new OrderStartedDomainEvent(fakeOrder, cardTypeId, cardNumber, cardSecurityNumber, cardHolderName, cardExpiration); var expectedResult = 1; //Act