-
-
Notifications
You must be signed in to change notification settings - Fork 525
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0b29171
commit 9e6c86b
Showing
10 changed files
with
257 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 20 additions & 2 deletions
22
Workshops/PracticalEventSourcing/Orders/Orders/Events/OrderCancelled.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,38 @@ | ||
using System; | ||
using Ardalis.GuardClauses; | ||
using Core.Events; | ||
|
||
namespace Orders.Orders.Events | ||
{ | ||
public class OrderCancelled: IEvent | ||
{ | ||
public Guid OrderId { get; } | ||
public Guid PaymentId { get; } | ||
public Guid? PaymentId { get; } | ||
|
||
public DateTime CancelledAt { get; } | ||
|
||
public OrderCancelled(Guid orderId, Guid paymentId, DateTime cancelledAt) | ||
public OrderCancelled( | ||
Guid orderId, | ||
Guid? paymentId, | ||
DateTime cancelledAt | ||
) | ||
{ | ||
OrderId = orderId; | ||
PaymentId = paymentId; | ||
CancelledAt = cancelledAt; | ||
} | ||
|
||
public static OrderCancelled Create( | ||
Guid orderId, | ||
Guid? paymentId, | ||
DateTime cancelledAt | ||
) | ||
{ | ||
Guard.Against.Default(orderId, nameof(orderId)); | ||
Guard.Against.Default(paymentId, nameof(paymentId)); | ||
Guard.Against.Default(cancelledAt, nameof(cancelledAt)); | ||
|
||
return new OrderCancelled(orderId, paymentId, cancelledAt); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,120 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Ardalis.GuardClauses; | ||
using Carts.Carts.ValueObjects; | ||
using Core.Aggregates; | ||
using Orders.Orders.Enums; | ||
using Orders.Orders.Events; | ||
|
||
namespace Orders.Orders | ||
{ | ||
public class Order: Aggregate | ||
{ | ||
public Guid? ClientId { get; private set; } | ||
|
||
public IReadOnlyList<PricedProductItem> ProductItems { get; private set; } | ||
public Guid PaymentId { get; private set; } | ||
|
||
public decimal TotalPrice { get; private set; } | ||
|
||
public OrderStatus Status { get; private set; } | ||
|
||
public Guid? PaymentId { get; private set; } | ||
|
||
public static Order Initialize( | ||
Guid clientId, | ||
IReadOnlyList<PricedProductItem> productItems, | ||
decimal totalPrice) | ||
{ | ||
var orderId = Guid.NewGuid(); | ||
|
||
return new Order( | ||
orderId, | ||
clientId, | ||
productItems, | ||
totalPrice | ||
); | ||
} | ||
|
||
private Order(Guid id, Guid clientId, IReadOnlyList<PricedProductItem> productItems, decimal totalPrice) | ||
{ | ||
var @event = OrderInitialized.Create( | ||
id, | ||
clientId, | ||
productItems, | ||
totalPrice, | ||
DateTime.UtcNow | ||
); | ||
|
||
Enqueue(@event); | ||
Apply(@event); | ||
} | ||
|
||
private void Apply(OrderInitialized @event) | ||
{ | ||
Version++; | ||
|
||
Id = @event.OrderId; | ||
ClientId = @event.ClientId; | ||
ProductItems = @event.ProductItems; | ||
Status = OrderStatus.Initialized; | ||
} | ||
|
||
public void RecordPayment(Guid paymentId, DateTime recordedAt) | ||
{ | ||
var @event = OrderPaymentRecorded.Create( | ||
Id, | ||
paymentId, | ||
ProductItems, | ||
TotalPrice, | ||
recordedAt | ||
); | ||
|
||
Enqueue(@event); | ||
Apply(@event); | ||
} | ||
|
||
private void Apply(OrderPaymentRecorded @event) | ||
{ | ||
Version++; | ||
|
||
PaymentId = @event.PaymentId; | ||
Status = OrderStatus.Paid; | ||
} | ||
|
||
public void Complete() | ||
{ | ||
if(Status != OrderStatus.Paid) | ||
throw new InvalidOperationException($"Cannot complete a not paid order."); | ||
|
||
var @event = OrderCompleted.Create(Id, DateTime.UtcNow); | ||
|
||
Enqueue(@event); | ||
Apply(@event); | ||
} | ||
|
||
private void Apply(OrderCompleted @event) | ||
{ | ||
Version++; | ||
|
||
Status = OrderStatus.Completed; | ||
} | ||
|
||
public void Cancel(OrderCancellationReason cancellationReason) | ||
{ | ||
if(OrderStatus.Closed.HasFlag(Status)) | ||
throw new InvalidOperationException($"Cannot cancel a closed order."); | ||
|
||
var @event = OrderCancelled.Create(Id, PaymentId, DateTime.UtcNow); | ||
|
||
Enqueue(@event); | ||
Apply(@event); | ||
} | ||
|
||
private void Apply(OrderCancelled @event) | ||
{ | ||
Version++; | ||
|
||
Status = OrderStatus.Cancelled; | ||
} | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
Workshops/PracticalEventSourcing/Orders/Orders/OrderCommandHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Ardalis.GuardClauses; | ||
using Core.Commands; | ||
using Core.Repositories; | ||
using MediatR; | ||
using Orders.Orders.Commands; | ||
|
||
namespace Orders.Orders | ||
{ | ||
public class OrderCommandHandler : | ||
ICommandHandler<InitOrder>, | ||
ICommandHandler<RecordOrderPayment>, | ||
ICommandHandler<CompleteOrder>, | ||
ICommandHandler<CancelOrder> | ||
{ | ||
private readonly IRepository<Order> orderRepository; | ||
|
||
public OrderCommandHandler(IRepository<Order> orderRepository) | ||
{ | ||
Guard.Against.Null(orderRepository, nameof(orderRepository)); | ||
|
||
this.orderRepository = orderRepository; | ||
} | ||
|
||
public async Task<Unit> Handle(InitOrder command, CancellationToken cancellationToken) | ||
{ | ||
var order = Order.Initialize(command.ClientId, command.ProductItems, command.TotalPrice); | ||
|
||
await orderRepository.Add(order, cancellationToken); | ||
|
||
return Unit.Value; | ||
} | ||
|
||
public Task<Unit> Handle(RecordOrderPayment command, CancellationToken cancellationToken) | ||
{ | ||
return orderRepository.GetAndUpdate( | ||
command.OrderId, | ||
order => order.RecordPayment(command.PaymentId, command.PaymentRecordedAt), | ||
cancellationToken); | ||
} | ||
|
||
public Task<Unit> Handle(CompleteOrder command, CancellationToken cancellationToken) | ||
{ | ||
return orderRepository.GetAndUpdate( | ||
command.OrderId, | ||
order => order.Complete(), | ||
cancellationToken); | ||
} | ||
|
||
public Task<Unit> Handle(CancelOrder command, CancellationToken cancellationToken) | ||
{ | ||
return orderRepository.GetAndUpdate( | ||
command.OrderId, | ||
order => order.Cancel(command.CancellationReason), | ||
cancellationToken); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.