diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs new file mode 100644 index 0000000..72c57b9 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using NServiceBus; +using Shipping.Contracts; + +namespace Sales.Features.ReadyToShip +{ + public class ShippingLabelCreatedHandler : IHandleMessages + { + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs new file mode 100644 index 0000000..72c57b9 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using NServiceBus; +using Shipping.Contracts; + +namespace Sales.Features.ReadyToShip +{ + public class ShippingLabelCreatedHandler : IHandleMessages + { + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Sales/PlaceOrderHandler.cs b/src/Sales/PlaceOrderHandler.cs deleted file mode 100644 index a2283d6..0000000 --- a/src/Sales/PlaceOrderHandler.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using Microsoft.AspNetCore.Mvc; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class PlaceOrderController : Controller - { - private readonly IMessageSession _messageSession; - - public PlaceOrderController(IMessageSession messageSession) - { - _messageSession = messageSession; - } - - [HttpPost("/sales/orders/{orderId:Guid}")] - public async Task Action([FromRoute] Guid orderId) - { - await _messageSession.Send(new PlaceOrder - { - OrderId = orderId - }); - - return NoContent(); - } - } - - public class PlaceOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public PlaceOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(PlaceOrder message, IMessageHandlerContext context) - { - await _dbContext.Orders.AddAsync(new Order - { - OrderId = message.OrderId, - Status = OrderStatus.Pending - }); - await _dbContext.SaveChangesAsync(); - - var orderPlaced = new OrderPlaced - { - OrderId = message.OrderId - }; - await context.Publish(orderPlaced); - } - } - - public class PlaceOrderSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool HasBeenBilled { get; set; } - } - - public class PlaceOrderSaga : - Saga, - IAmStartedByMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages - { - - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Send(new BillOrder - { - OrderId = message.OrderId - }); - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.HasBeenBilled = true; - - await context.Send(new CreateShippingLabel - { - OrderId = message.OrderId - }); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await context.SendLocal(new ReadyToShipOrder - { - OrderId = Data.OrderId - }); - MarkAsComplete(); - } - - public async Task Handle(Backordered message, IMessageHandlerContext context) - { - if (Data.HasBeenBilled) - { - await context.Send(new RefundOrder() - { - OrderId = message.OrderId - }); - } - else - { - MarkAsComplete(); - } - } - - public async Task Handle(OrderRefunded message, IMessageHandlerContext context) - { - await context.SendLocal(new CancelOrder - { - OrderId = message.OrderId - }); - MarkAsComplete(); - } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs new file mode 100644 index 0000000..72c57b9 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using NServiceBus; +using Shipping.Contracts; + +namespace Sales.Features.ReadyToShip +{ + public class ShippingLabelCreatedHandler : IHandleMessages + { + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Sales/PlaceOrderHandler.cs b/src/Sales/PlaceOrderHandler.cs deleted file mode 100644 index a2283d6..0000000 --- a/src/Sales/PlaceOrderHandler.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using Microsoft.AspNetCore.Mvc; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class PlaceOrderController : Controller - { - private readonly IMessageSession _messageSession; - - public PlaceOrderController(IMessageSession messageSession) - { - _messageSession = messageSession; - } - - [HttpPost("/sales/orders/{orderId:Guid}")] - public async Task Action([FromRoute] Guid orderId) - { - await _messageSession.Send(new PlaceOrder - { - OrderId = orderId - }); - - return NoContent(); - } - } - - public class PlaceOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public PlaceOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(PlaceOrder message, IMessageHandlerContext context) - { - await _dbContext.Orders.AddAsync(new Order - { - OrderId = message.OrderId, - Status = OrderStatus.Pending - }); - await _dbContext.SaveChangesAsync(); - - var orderPlaced = new OrderPlaced - { - OrderId = message.OrderId - }; - await context.Publish(orderPlaced); - } - } - - public class PlaceOrderSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool HasBeenBilled { get; set; } - } - - public class PlaceOrderSaga : - Saga, - IAmStartedByMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages - { - - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Send(new BillOrder - { - OrderId = message.OrderId - }); - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.HasBeenBilled = true; - - await context.Send(new CreateShippingLabel - { - OrderId = message.OrderId - }); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await context.SendLocal(new ReadyToShipOrder - { - OrderId = Data.OrderId - }); - MarkAsComplete(); - } - - public async Task Handle(Backordered message, IMessageHandlerContext context) - { - if (Data.HasBeenBilled) - { - await context.Send(new RefundOrder() - { - OrderId = message.OrderId - }); - } - else - { - MarkAsComplete(); - } - } - - public async Task Handle(OrderRefunded message, IMessageHandlerContext context) - { - await context.SendLocal(new CancelOrder - { - OrderId = message.OrderId - }); - MarkAsComplete(); - } - } -} \ No newline at end of file diff --git a/src/Sales/ReadyToShipHandler.cs b/src/Sales/ReadyToShipHandler.cs deleted file mode 100644 index 2b6541c..0000000 --- a/src/Sales/ReadyToShipHandler.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class ReadyToShipHandler : - IHandleMessages, - IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public ReadyToShipHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - private async Task SetStatus(Guid orderId) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == orderId); - order.Status = OrderStatus.ReadyToShip; - await _dbContext.SaveChangesAsync(); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - - public async Task Handle(ReadyToShipOrder message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs new file mode 100644 index 0000000..72c57b9 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using NServiceBus; +using Shipping.Contracts; + +namespace Sales.Features.ReadyToShip +{ + public class ShippingLabelCreatedHandler : IHandleMessages + { + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Sales/PlaceOrderHandler.cs b/src/Sales/PlaceOrderHandler.cs deleted file mode 100644 index a2283d6..0000000 --- a/src/Sales/PlaceOrderHandler.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using Microsoft.AspNetCore.Mvc; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class PlaceOrderController : Controller - { - private readonly IMessageSession _messageSession; - - public PlaceOrderController(IMessageSession messageSession) - { - _messageSession = messageSession; - } - - [HttpPost("/sales/orders/{orderId:Guid}")] - public async Task Action([FromRoute] Guid orderId) - { - await _messageSession.Send(new PlaceOrder - { - OrderId = orderId - }); - - return NoContent(); - } - } - - public class PlaceOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public PlaceOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(PlaceOrder message, IMessageHandlerContext context) - { - await _dbContext.Orders.AddAsync(new Order - { - OrderId = message.OrderId, - Status = OrderStatus.Pending - }); - await _dbContext.SaveChangesAsync(); - - var orderPlaced = new OrderPlaced - { - OrderId = message.OrderId - }; - await context.Publish(orderPlaced); - } - } - - public class PlaceOrderSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool HasBeenBilled { get; set; } - } - - public class PlaceOrderSaga : - Saga, - IAmStartedByMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages - { - - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Send(new BillOrder - { - OrderId = message.OrderId - }); - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.HasBeenBilled = true; - - await context.Send(new CreateShippingLabel - { - OrderId = message.OrderId - }); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await context.SendLocal(new ReadyToShipOrder - { - OrderId = Data.OrderId - }); - MarkAsComplete(); - } - - public async Task Handle(Backordered message, IMessageHandlerContext context) - { - if (Data.HasBeenBilled) - { - await context.Send(new RefundOrder() - { - OrderId = message.OrderId - }); - } - else - { - MarkAsComplete(); - } - } - - public async Task Handle(OrderRefunded message, IMessageHandlerContext context) - { - await context.SendLocal(new CancelOrder - { - OrderId = message.OrderId - }); - MarkAsComplete(); - } - } -} \ No newline at end of file diff --git a/src/Sales/ReadyToShipHandler.cs b/src/Sales/ReadyToShipHandler.cs deleted file mode 100644 index 2b6541c..0000000 --- a/src/Sales/ReadyToShipHandler.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class ReadyToShipHandler : - IHandleMessages, - IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public ReadyToShipHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - private async Task SetStatus(Guid orderId) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == orderId); - order.Status = OrderStatus.ReadyToShip; - await _dbContext.SaveChangesAsync(); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - - public async Task Handle(ReadyToShipOrder message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - } -} \ No newline at end of file diff --git a/src/Shipping/CancelShippingLabelHandler.cs b/src/Shipping/CancelShippingLabelHandler.cs deleted file mode 100644 index b4e03a9..0000000 --- a/src/Shipping/CancelShippingLabelHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Shipping -{ - public class CancelShippingLabelHandler : IHandleMessages - { - private readonly ShippingDbContext _dbContext; - - public CancelShippingLabelHandler(ShippingDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(OrderCancelled message, IMessageHandlerContext context) - { - var order = await _dbContext.ShippingLabels.SingleAsync(x => x.OrderId == message.OrderId); - order.Cancelled = true; - await _dbContext.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs new file mode 100644 index 0000000..72c57b9 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using NServiceBus; +using Shipping.Contracts; + +namespace Sales.Features.ReadyToShip +{ + public class ShippingLabelCreatedHandler : IHandleMessages + { + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Sales/PlaceOrderHandler.cs b/src/Sales/PlaceOrderHandler.cs deleted file mode 100644 index a2283d6..0000000 --- a/src/Sales/PlaceOrderHandler.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using Microsoft.AspNetCore.Mvc; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class PlaceOrderController : Controller - { - private readonly IMessageSession _messageSession; - - public PlaceOrderController(IMessageSession messageSession) - { - _messageSession = messageSession; - } - - [HttpPost("/sales/orders/{orderId:Guid}")] - public async Task Action([FromRoute] Guid orderId) - { - await _messageSession.Send(new PlaceOrder - { - OrderId = orderId - }); - - return NoContent(); - } - } - - public class PlaceOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public PlaceOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(PlaceOrder message, IMessageHandlerContext context) - { - await _dbContext.Orders.AddAsync(new Order - { - OrderId = message.OrderId, - Status = OrderStatus.Pending - }); - await _dbContext.SaveChangesAsync(); - - var orderPlaced = new OrderPlaced - { - OrderId = message.OrderId - }; - await context.Publish(orderPlaced); - } - } - - public class PlaceOrderSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool HasBeenBilled { get; set; } - } - - public class PlaceOrderSaga : - Saga, - IAmStartedByMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages - { - - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Send(new BillOrder - { - OrderId = message.OrderId - }); - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.HasBeenBilled = true; - - await context.Send(new CreateShippingLabel - { - OrderId = message.OrderId - }); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await context.SendLocal(new ReadyToShipOrder - { - OrderId = Data.OrderId - }); - MarkAsComplete(); - } - - public async Task Handle(Backordered message, IMessageHandlerContext context) - { - if (Data.HasBeenBilled) - { - await context.Send(new RefundOrder() - { - OrderId = message.OrderId - }); - } - else - { - MarkAsComplete(); - } - } - - public async Task Handle(OrderRefunded message, IMessageHandlerContext context) - { - await context.SendLocal(new CancelOrder - { - OrderId = message.OrderId - }); - MarkAsComplete(); - } - } -} \ No newline at end of file diff --git a/src/Sales/ReadyToShipHandler.cs b/src/Sales/ReadyToShipHandler.cs deleted file mode 100644 index 2b6541c..0000000 --- a/src/Sales/ReadyToShipHandler.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class ReadyToShipHandler : - IHandleMessages, - IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public ReadyToShipHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - private async Task SetStatus(Guid orderId) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == orderId); - order.Status = OrderStatus.ReadyToShip; - await _dbContext.SaveChangesAsync(); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - - public async Task Handle(ReadyToShipOrder message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - } -} \ No newline at end of file diff --git a/src/Shipping/CancelShippingLabelHandler.cs b/src/Shipping/CancelShippingLabelHandler.cs deleted file mode 100644 index b4e03a9..0000000 --- a/src/Shipping/CancelShippingLabelHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Shipping -{ - public class CancelShippingLabelHandler : IHandleMessages - { - private readonly ShippingDbContext _dbContext; - - public CancelShippingLabelHandler(ShippingDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(OrderCancelled message, IMessageHandlerContext context) - { - var order = await _dbContext.ShippingLabels.SingleAsync(x => x.OrderId == message.OrderId); - order.Cancelled = true; - await _dbContext.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/src/Shipping/CreateShippingLabelHandler.cs b/src/Shipping/CreateShippingLabelHandler.cs deleted file mode 100644 index 700667a..0000000 --- a/src/Shipping/CreateShippingLabelHandler.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Shipping -{ - public class CreateShippingLabelHandler : - //IHandleMessages, - IHandleMessages - { - private readonly ShippingDbContext _dbContext; - - public CreateShippingLabelHandler(ShippingDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - await _dbContext.ShippingLabels.AddAsync(new ShippingLabel - { - OrderId = message.OrderId, - OrderDate = DateTime.UtcNow - }); - await _dbContext.SaveChangesAsync(); - - await context.Publish(created => - { - created.OrderId = message.OrderId; - }); - } - - public async Task Handle(CreateShippingLabel message, IMessageHandlerContext context) - { - await _dbContext.ShippingLabels.AddAsync(new ShippingLabel - { - OrderId = message.OrderId, - OrderDate = DateTime.UtcNow - }); - await _dbContext.SaveChangesAsync(); - - await context.Publish(created => - { - created.OrderId = message.OrderId; - }); - - /* - await context.Publish(backordered => - { - backordered.OrderId = message.OrderId; - }); - */ - } - } - - public class CreateShippingLabelSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool IsOrderPlaced { get; set; } - public bool IsOrderBilled { get; set; } - } - - public class CreateShippingLabelSaga : Saga, - IAmStartedByMessages, - IAmStartedByMessages - { - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - Data.IsOrderPlaced = true; - return ProcessOrder(context); - } - - public Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.IsOrderBilled = true; - return ProcessOrder(context); - } - - private async Task ProcessOrder(IMessageHandlerContext context) - { - if (Data.IsOrderPlaced && Data.IsOrderBilled) - { - await context.SendLocal(new CreateShippingLabel() { OrderId = Data.OrderId }); - MarkAsComplete(); - } - } - } -} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs new file mode 100644 index 0000000..72c57b9 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using NServiceBus; +using Shipping.Contracts; + +namespace Sales.Features.ReadyToShip +{ + public class ShippingLabelCreatedHandler : IHandleMessages + { + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Sales/PlaceOrderHandler.cs b/src/Sales/PlaceOrderHandler.cs deleted file mode 100644 index a2283d6..0000000 --- a/src/Sales/PlaceOrderHandler.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using Microsoft.AspNetCore.Mvc; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class PlaceOrderController : Controller - { - private readonly IMessageSession _messageSession; - - public PlaceOrderController(IMessageSession messageSession) - { - _messageSession = messageSession; - } - - [HttpPost("/sales/orders/{orderId:Guid}")] - public async Task Action([FromRoute] Guid orderId) - { - await _messageSession.Send(new PlaceOrder - { - OrderId = orderId - }); - - return NoContent(); - } - } - - public class PlaceOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public PlaceOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(PlaceOrder message, IMessageHandlerContext context) - { - await _dbContext.Orders.AddAsync(new Order - { - OrderId = message.OrderId, - Status = OrderStatus.Pending - }); - await _dbContext.SaveChangesAsync(); - - var orderPlaced = new OrderPlaced - { - OrderId = message.OrderId - }; - await context.Publish(orderPlaced); - } - } - - public class PlaceOrderSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool HasBeenBilled { get; set; } - } - - public class PlaceOrderSaga : - Saga, - IAmStartedByMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages - { - - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Send(new BillOrder - { - OrderId = message.OrderId - }); - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.HasBeenBilled = true; - - await context.Send(new CreateShippingLabel - { - OrderId = message.OrderId - }); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await context.SendLocal(new ReadyToShipOrder - { - OrderId = Data.OrderId - }); - MarkAsComplete(); - } - - public async Task Handle(Backordered message, IMessageHandlerContext context) - { - if (Data.HasBeenBilled) - { - await context.Send(new RefundOrder() - { - OrderId = message.OrderId - }); - } - else - { - MarkAsComplete(); - } - } - - public async Task Handle(OrderRefunded message, IMessageHandlerContext context) - { - await context.SendLocal(new CancelOrder - { - OrderId = message.OrderId - }); - MarkAsComplete(); - } - } -} \ No newline at end of file diff --git a/src/Sales/ReadyToShipHandler.cs b/src/Sales/ReadyToShipHandler.cs deleted file mode 100644 index 2b6541c..0000000 --- a/src/Sales/ReadyToShipHandler.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class ReadyToShipHandler : - IHandleMessages, - IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public ReadyToShipHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - private async Task SetStatus(Guid orderId) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == orderId); - order.Status = OrderStatus.ReadyToShip; - await _dbContext.SaveChangesAsync(); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - - public async Task Handle(ReadyToShipOrder message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - } -} \ No newline at end of file diff --git a/src/Shipping/CancelShippingLabelHandler.cs b/src/Shipping/CancelShippingLabelHandler.cs deleted file mode 100644 index b4e03a9..0000000 --- a/src/Shipping/CancelShippingLabelHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Shipping -{ - public class CancelShippingLabelHandler : IHandleMessages - { - private readonly ShippingDbContext _dbContext; - - public CancelShippingLabelHandler(ShippingDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(OrderCancelled message, IMessageHandlerContext context) - { - var order = await _dbContext.ShippingLabels.SingleAsync(x => x.OrderId == message.OrderId); - order.Cancelled = true; - await _dbContext.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/src/Shipping/CreateShippingLabelHandler.cs b/src/Shipping/CreateShippingLabelHandler.cs deleted file mode 100644 index 700667a..0000000 --- a/src/Shipping/CreateShippingLabelHandler.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Shipping -{ - public class CreateShippingLabelHandler : - //IHandleMessages, - IHandleMessages - { - private readonly ShippingDbContext _dbContext; - - public CreateShippingLabelHandler(ShippingDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - await _dbContext.ShippingLabels.AddAsync(new ShippingLabel - { - OrderId = message.OrderId, - OrderDate = DateTime.UtcNow - }); - await _dbContext.SaveChangesAsync(); - - await context.Publish(created => - { - created.OrderId = message.OrderId; - }); - } - - public async Task Handle(CreateShippingLabel message, IMessageHandlerContext context) - { - await _dbContext.ShippingLabels.AddAsync(new ShippingLabel - { - OrderId = message.OrderId, - OrderDate = DateTime.UtcNow - }); - await _dbContext.SaveChangesAsync(); - - await context.Publish(created => - { - created.OrderId = message.OrderId; - }); - - /* - await context.Publish(backordered => - { - backordered.OrderId = message.OrderId; - }); - */ - } - } - - public class CreateShippingLabelSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool IsOrderPlaced { get; set; } - public bool IsOrderBilled { get; set; } - } - - public class CreateShippingLabelSaga : Saga, - IAmStartedByMessages, - IAmStartedByMessages - { - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - Data.IsOrderPlaced = true; - return ProcessOrder(context); - } - - public Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.IsOrderBilled = true; - return ProcessOrder(context); - } - - private async Task ProcessOrder(IMessageHandlerContext context) - { - if (Data.IsOrderPlaced && Data.IsOrderBilled) - { - await context.SendLocal(new CreateShippingLabel() { OrderId = Data.OrderId }); - MarkAsComplete(); - } - } - } -} \ No newline at end of file diff --git a/src/Shipping/Features/CancelShippingLabel.cs b/src/Shipping/Features/CancelShippingLabel.cs new file mode 100644 index 0000000..45bb892 --- /dev/null +++ b/src/Shipping/Features/CancelShippingLabel.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Shipping +{ + public static class CancelShippingLabel + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly ShippingDbContext _dbContext; + + public Handler(ShippingDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.ShippingLabels.SingleAsync(x => x.OrderId == message.OrderId); + order.Cancelled = true; + await _dbContext.SaveChangesAsync(); + } + } + + public class OnOrderCancelled : IHandleMessages + { + public async Task Handle(OrderCancelled message, IMessageHandlerContext context) + { + await context.SendLocal(new Command + { + OrderId = message.OrderId + }); + } + } + } +} \ No newline at end of file diff --git a/src/Billing/BillOrder.cs b/src/Billing/BillOrder.cs deleted file mode 100644 index 4a3b51f..0000000 --- a/src/Billing/BillOrder.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; - -namespace Billing -{ - public class BillOrder : IHandleMessages - { - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Publish(new OrderBilled - { - OrderId = message.OrderId - }); - } - } -} \ No newline at end of file diff --git a/src/Billing/Features/BillOrder.cs b/src/Billing/Features/BillOrder.cs new file mode 100644 index 0000000..4a3b51f --- /dev/null +++ b/src/Billing/Features/BillOrder.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; + +namespace Billing +{ + public class BillOrder : IHandleMessages + { + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Publish(new OrderBilled + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/Features/RefundOrder.cs b/src/Billing/Features/RefundOrder.cs new file mode 100644 index 0000000..0e4afb4 --- /dev/null +++ b/src/Billing/Features/RefundOrder.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; + +namespace Billing +{ + public class RefundOrderHandler : IHandleMessages + { + public async Task Handle(RefundOrder message, IMessageHandlerContext context) + { + await context.Publish(refunded => + { + refunded.OrderId = message.OrderId; + }); + } + } +} \ No newline at end of file diff --git a/src/Billing/RefundOrderHandler.cs b/src/Billing/RefundOrderHandler.cs deleted file mode 100644 index 0e4afb4..0000000 --- a/src/Billing/RefundOrderHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; - -namespace Billing -{ - public class RefundOrderHandler : IHandleMessages - { - public async Task Handle(RefundOrder message, IMessageHandlerContext context) - { - await context.Publish(refunded => - { - refunded.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/MessagingNamingStructure.sln.DotSettings b/src/MessagingNamingStructure.sln.DotSettings new file mode 100644 index 0000000..e1ed010 --- /dev/null +++ b/src/MessagingNamingStructure.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/Sales.Contracts/CancelOrder.cs b/src/Sales.Contracts/CancelOrder.cs deleted file mode 100644 index f264adb..0000000 --- a/src/Sales.Contracts/CancelOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class CancelOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales.Contracts/PlaceOrder.cs b/src/Sales.Contracts/PlaceOrder.cs deleted file mode 100644 index 20ca626..0000000 --- a/src/Sales.Contracts/PlaceOrder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; -using NServiceBus; - -public class PlaceOrder : ICommand -{ - public Guid OrderId { get; set; } -} \ No newline at end of file diff --git a/src/Sales.Contracts/ReadyToShipOrder.cs b/src/Sales.Contracts/ReadyToShipOrder.cs deleted file mode 100644 index e6fa0f6..0000000 --- a/src/Sales.Contracts/ReadyToShipOrder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using NServiceBus; - -namespace Sales.Contracts -{ - public class ReadyToShipOrder : ICommand - { - public Guid OrderId { get; set; } - } -} \ No newline at end of file diff --git a/src/Sales/CancelOrderHandler.cs b/src/Sales/CancelOrderHandler.cs deleted file mode 100644 index 1c86008..0000000 --- a/src/Sales/CancelOrderHandler.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Sales -{ - public class CancelOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public CancelOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(CancelOrder message, IMessageHandlerContext context) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); - order.Status = OrderStatus.Cancelled; - await _dbContext.SaveChangesAsync(); - - await context.Publish(cancelled => - { - cancelled.OrderId = message.OrderId; - }); - } - } -} \ No newline at end of file diff --git a/src/Sales/Features/CancelOrder.cs b/src/Sales/Features/CancelOrder.cs new file mode 100644 index 0000000..755b088 --- /dev/null +++ b/src/Sales/Features/CancelOrder.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Sales +{ + public static class CancelOrder + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public Handler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.Cancelled; + await _dbContext.SaveChangesAsync(); + + await context.Publish(cancelled => + { + cancelled.OrderId = message.OrderId; + }); + } + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/PlaceOrder.cs b/src/Sales/Features/PlaceOrder.cs new file mode 100644 index 0000000..cc64430 --- /dev/null +++ b/src/Sales/Features/PlaceOrder.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using Microsoft.AspNetCore.Mvc; +using NServiceBus; +using Sales.Contracts; +using Sales.Features.ReadyToShip; +using Shipping.Contracts; + +namespace Sales +{ + public class PlaceOrderController : Controller + { + private readonly IMessageSession _messageSession; + + public PlaceOrderController(IMessageSession messageSession) + { + _messageSession = messageSession; + } + + [HttpPost("/sales/orders/{orderId:Guid}")] + public async Task Action([FromRoute] Guid orderId) + { + await _messageSession.Send(new PlaceOrderCommand + { + OrderId = orderId + }); + + return NoContent(); + } + } + + public class PlaceOrderCommand : ICommand + { + public Guid OrderId { get; set; } + } + + public class PlaceOrderHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public PlaceOrderHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(PlaceOrderCommand message, IMessageHandlerContext context) + { + await _dbContext.Orders.AddAsync(new Order + { + OrderId = message.OrderId, + Status = OrderStatus.Pending + }); + await _dbContext.SaveChangesAsync(); + + var orderPlaced = new OrderPlaced + { + OrderId = message.OrderId + }; + await context.Publish(orderPlaced); + } + } + + public class PlaceOrderSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool HasBeenBilled { get; set; } + } + + public class PlaceOrderSaga : + Saga, + IAmStartedByMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages, + IHandleMessages + { + + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public async Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + await context.Send(new BillOrder + { + OrderId = message.OrderId + }); + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.HasBeenBilled = true; + + await context.Send(new CreateShippingLabel + { + OrderId = message.OrderId + }); + } + + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = Data.OrderId + }); + MarkAsComplete(); + } + + public async Task Handle(Backordered message, IMessageHandlerContext context) + { + if (Data.HasBeenBilled) + { + await context.Send(new RefundOrder() + { + OrderId = message.OrderId + }); + } + else + { + MarkAsComplete(); + } + } + + public async Task Handle(OrderRefunded message, IMessageHandlerContext context) + { + await context.SendLocal(new CancelOrder.Command() + { + OrderId = message.OrderId + }); + MarkAsComplete(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs new file mode 100644 index 0000000..8b98042 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipHandler.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipHandler : IHandleMessages + { + private readonly SalesDbContext _dbContext; + + public ReadyToShipHandler(SalesDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(ReadyToShipOrderCommand message, IMessageHandlerContext context) + { + var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == message.OrderId); + order.Status = OrderStatus.ReadyToShip; + await _dbContext.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs new file mode 100644 index 0000000..efd6fca --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ReadyToShipOrderCommand.cs @@ -0,0 +1,10 @@ +using System; +using NServiceBus; + +namespace Sales.Features.ReadyToShip +{ + public class ReadyToShipOrderCommand: ICommand + { + public Guid OrderId { get; set; } + } +} \ No newline at end of file diff --git a/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs new file mode 100644 index 0000000..72c57b9 --- /dev/null +++ b/src/Sales/Features/ReadyToShip/ShippingLabelCreatedHandler.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using NServiceBus; +using Shipping.Contracts; + +namespace Sales.Features.ReadyToShip +{ + public class ShippingLabelCreatedHandler : IHandleMessages + { + public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) + { + await context.SendLocal(new ReadyToShipOrderCommand + { + OrderId = message.OrderId + }); + } + } +} \ No newline at end of file diff --git a/src/Sales/PlaceOrderHandler.cs b/src/Sales/PlaceOrderHandler.cs deleted file mode 100644 index a2283d6..0000000 --- a/src/Sales/PlaceOrderHandler.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using Microsoft.AspNetCore.Mvc; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class PlaceOrderController : Controller - { - private readonly IMessageSession _messageSession; - - public PlaceOrderController(IMessageSession messageSession) - { - _messageSession = messageSession; - } - - [HttpPost("/sales/orders/{orderId:Guid}")] - public async Task Action([FromRoute] Guid orderId) - { - await _messageSession.Send(new PlaceOrder - { - OrderId = orderId - }); - - return NoContent(); - } - } - - public class PlaceOrderHandler : IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public PlaceOrderHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(PlaceOrder message, IMessageHandlerContext context) - { - await _dbContext.Orders.AddAsync(new Order - { - OrderId = message.OrderId, - Status = OrderStatus.Pending - }); - await _dbContext.SaveChangesAsync(); - - var orderPlaced = new OrderPlaced - { - OrderId = message.OrderId - }; - await context.Publish(orderPlaced); - } - } - - public class PlaceOrderSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool HasBeenBilled { get; set; } - } - - public class PlaceOrderSaga : - Saga, - IAmStartedByMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages, - IHandleMessages - { - - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public async Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - await context.Send(new BillOrder - { - OrderId = message.OrderId - }); - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.HasBeenBilled = true; - - await context.Send(new CreateShippingLabel - { - OrderId = message.OrderId - }); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await context.SendLocal(new ReadyToShipOrder - { - OrderId = Data.OrderId - }); - MarkAsComplete(); - } - - public async Task Handle(Backordered message, IMessageHandlerContext context) - { - if (Data.HasBeenBilled) - { - await context.Send(new RefundOrder() - { - OrderId = message.OrderId - }); - } - else - { - MarkAsComplete(); - } - } - - public async Task Handle(OrderRefunded message, IMessageHandlerContext context) - { - await context.SendLocal(new CancelOrder - { - OrderId = message.OrderId - }); - MarkAsComplete(); - } - } -} \ No newline at end of file diff --git a/src/Sales/ReadyToShipHandler.cs b/src/Sales/ReadyToShipHandler.cs deleted file mode 100644 index 2b6541c..0000000 --- a/src/Sales/ReadyToShipHandler.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Sales -{ - public class ReadyToShipHandler : - IHandleMessages, - IHandleMessages - { - private readonly SalesDbContext _dbContext; - - public ReadyToShipHandler(SalesDbContext dbContext) - { - _dbContext = dbContext; - } - - private async Task SetStatus(Guid orderId) - { - var order = await _dbContext.Orders.SingleAsync(x => x.OrderId == orderId); - order.Status = OrderStatus.ReadyToShip; - await _dbContext.SaveChangesAsync(); - } - - public async Task Handle(ShippingLabelCreated message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - - public async Task Handle(ReadyToShipOrder message, IMessageHandlerContext context) - { - await SetStatus(message.OrderId); - } - } -} \ No newline at end of file diff --git a/src/Shipping/CancelShippingLabelHandler.cs b/src/Shipping/CancelShippingLabelHandler.cs deleted file mode 100644 index b4e03a9..0000000 --- a/src/Shipping/CancelShippingLabelHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using NServiceBus; -using Sales.Contracts; - -namespace Shipping -{ - public class CancelShippingLabelHandler : IHandleMessages - { - private readonly ShippingDbContext _dbContext; - - public CancelShippingLabelHandler(ShippingDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(OrderCancelled message, IMessageHandlerContext context) - { - var order = await _dbContext.ShippingLabels.SingleAsync(x => x.OrderId == message.OrderId); - order.Cancelled = true; - await _dbContext.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/src/Shipping/CreateShippingLabelHandler.cs b/src/Shipping/CreateShippingLabelHandler.cs deleted file mode 100644 index 700667a..0000000 --- a/src/Shipping/CreateShippingLabelHandler.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Threading.Tasks; -using Billing.Contracts; -using NServiceBus; -using Sales.Contracts; -using Shipping.Contracts; - -namespace Shipping -{ - public class CreateShippingLabelHandler : - //IHandleMessages, - IHandleMessages - { - private readonly ShippingDbContext _dbContext; - - public CreateShippingLabelHandler(ShippingDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(OrderBilled message, IMessageHandlerContext context) - { - await _dbContext.ShippingLabels.AddAsync(new ShippingLabel - { - OrderId = message.OrderId, - OrderDate = DateTime.UtcNow - }); - await _dbContext.SaveChangesAsync(); - - await context.Publish(created => - { - created.OrderId = message.OrderId; - }); - } - - public async Task Handle(CreateShippingLabel message, IMessageHandlerContext context) - { - await _dbContext.ShippingLabels.AddAsync(new ShippingLabel - { - OrderId = message.OrderId, - OrderDate = DateTime.UtcNow - }); - await _dbContext.SaveChangesAsync(); - - await context.Publish(created => - { - created.OrderId = message.OrderId; - }); - - /* - await context.Publish(backordered => - { - backordered.OrderId = message.OrderId; - }); - */ - } - } - - public class CreateShippingLabelSagaData : ContainSagaData - { - public Guid OrderId { get; set; } - public bool IsOrderPlaced { get; set; } - public bool IsOrderBilled { get; set; } - } - - public class CreateShippingLabelSaga : Saga, - IAmStartedByMessages, - IAmStartedByMessages - { - protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) - { - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); - } - - public Task Handle(OrderPlaced message, IMessageHandlerContext context) - { - Data.IsOrderPlaced = true; - return ProcessOrder(context); - } - - public Task Handle(OrderBilled message, IMessageHandlerContext context) - { - Data.IsOrderBilled = true; - return ProcessOrder(context); - } - - private async Task ProcessOrder(IMessageHandlerContext context) - { - if (Data.IsOrderPlaced && Data.IsOrderBilled) - { - await context.SendLocal(new CreateShippingLabel() { OrderId = Data.OrderId }); - MarkAsComplete(); - } - } - } -} \ No newline at end of file diff --git a/src/Shipping/Features/CancelShippingLabel.cs b/src/Shipping/Features/CancelShippingLabel.cs new file mode 100644 index 0000000..45bb892 --- /dev/null +++ b/src/Shipping/Features/CancelShippingLabel.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using NServiceBus; +using Sales.Contracts; + +namespace Shipping +{ + public static class CancelShippingLabel + { + public class Command : ICommand + { + public Guid OrderId { get; set; } + } + + public class Handler : IHandleMessages + { + private readonly ShippingDbContext _dbContext; + + public Handler(ShippingDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Command message, IMessageHandlerContext context) + { + var order = await _dbContext.ShippingLabels.SingleAsync(x => x.OrderId == message.OrderId); + order.Cancelled = true; + await _dbContext.SaveChangesAsync(); + } + } + + public class OnOrderCancelled : IHandleMessages + { + public async Task Handle(OrderCancelled message, IMessageHandlerContext context) + { + await context.SendLocal(new Command + { + OrderId = message.OrderId + }); + } + } + } +} \ No newline at end of file diff --git a/src/Shipping/Features/CreateShippingLabel.cs b/src/Shipping/Features/CreateShippingLabel.cs new file mode 100644 index 0000000..9860392 --- /dev/null +++ b/src/Shipping/Features/CreateShippingLabel.cs @@ -0,0 +1,89 @@ +using System; +using System.Threading.Tasks; +using Billing.Contracts; +using NServiceBus; +using Sales.Contracts; +using Shipping.Contracts; + +namespace Shipping +{ + public class CreateShippingLabelHandler : IHandleMessages + { + private readonly ShippingDbContext _dbContext; + + public CreateShippingLabelHandler(ShippingDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(OrderBilled message, IMessageHandlerContext context) + { + await _dbContext.ShippingLabels.AddAsync(new ShippingLabel + { + OrderId = message.OrderId, + OrderDate = DateTime.UtcNow + }); + await _dbContext.SaveChangesAsync(); + + await context.Publish(created => + { + created.OrderId = message.OrderId; + }); + } + + public async Task Handle(CreateShippingLabel message, IMessageHandlerContext context) + { + await _dbContext.ShippingLabels.AddAsync(new ShippingLabel + { + OrderId = message.OrderId, + OrderDate = DateTime.UtcNow + }); + await _dbContext.SaveChangesAsync(); + + await context.Publish(created => + { + created.OrderId = message.OrderId; + }); + } + } + + public class CreateShippingLabelSagaData : ContainSagaData + { + public Guid OrderId { get; set; } + public bool IsOrderPlaced { get; set; } + public bool IsOrderBilled { get; set; } + } + + public class CreateShippingLabelSaga : + Saga, + IAmStartedByMessages, + IAmStartedByMessages + { + protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) + { + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + mapper.ConfigureMapping(message => message.OrderId).ToSaga(sagaData => sagaData.OrderId); + } + + public Task Handle(OrderPlaced message, IMessageHandlerContext context) + { + Data.IsOrderPlaced = true; + return ProcessOrder(context); + } + + public Task Handle(OrderBilled message, IMessageHandlerContext context) + { + Data.IsOrderBilled = true; + return ProcessOrder(context); + } + + private async Task ProcessOrder(IMessageHandlerContext context) + { + if (Data.IsOrderPlaced && Data.IsOrderBilled) + { + await context.SendLocal(new CreateShippingLabel { OrderId = Data.OrderId }); + MarkAsComplete(); + } + } + } +} \ No newline at end of file