Created
October 22, 2018 19:51
-
-
Save adamralph/5dc87f9d7f0390108697f87dec6f11cd to your computer and use it in GitHub Desktop.
My solution to the saga homework for https://particular.net/adsd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace UdiWorld | |
{ | |
using System; | |
using System.Threading.Tasks; | |
using NServiceBus; | |
public class UserBecamePreferred | |
{ | |
public Guid UserId { get; set; } | |
} | |
public class UserBecameUnpreferred | |
{ | |
public Guid UserId { get; set; } | |
} | |
public class UdiCoinsPurchased | |
{ | |
public Guid UserId { get; set; } | |
public int Amount { get; set; } | |
} | |
public class BuyItem | |
{ | |
public Guid UserId { get; set; } | |
public Guid ItemId { get; set; } | |
public int Price { get; set; } | |
} | |
public class DecrementOneWeekTotal | |
{ | |
public int Amount { get; set; } | |
} | |
public class DecrementTwoWeekTotal | |
{ | |
public int Amount { get; set; } | |
} | |
public class FulfillPurchase | |
{ | |
public Guid UserId { get; set; } | |
public Guid ItemId { get; set; } | |
} | |
public class BalanceInsufficient | |
{ | |
public Guid UserId { get; set; } | |
public Guid ItemId { get; set; } | |
} | |
public class InAppPurchases : Saga<InAppPurchases.State>, | |
IAmStartedByMessages<UserBecamePreferred>, | |
IAmStartedByMessages<UserBecameUnpreferred>, | |
IAmStartedByMessages<UdiCoinsPurchased>, | |
IAmStartedByMessages<BuyItem>, | |
IHandleTimeouts<DecrementOneWeekTotal>, | |
IHandleTimeouts<DecrementTwoWeekTotal> | |
{ | |
public Task Handle(UserBecamePreferred message, IMessageHandlerContext context) | |
{ | |
Data.IsPreferred = true; | |
return Task.CompletedTask; | |
} | |
public Task Handle(UserBecameUnpreferred message, IMessageHandlerContext context) | |
{ | |
Data.IsPreferred = false; | |
return Task.CompletedTask; | |
} | |
public Task Handle(UdiCoinsPurchased message, IMessageHandlerContext context) | |
{ | |
Data.Balance += message.Amount; | |
return Task.CompletedTask; | |
} | |
public async Task Handle(BuyItem message, IMessageHandlerContext context) | |
{ | |
var totalOrderValue = Data.IsPreferred | |
? Data.TwoWeekTotal | |
: Data.OneWeekTotal; | |
var discount = totalOrderValue > 100 | |
? 0.2 | |
: 0.1; | |
var price = (int)(message.Price * (1 - discount)); | |
if (Data.Balance > price) | |
{ | |
Data.Balance -= price; | |
Data.OneWeekTotal += message.Price; | |
await RequestTimeout(context, TimeSpan.FromDays(7), new DecrementOneWeekTotal { Amount = message.Price }); | |
Data.TwoWeekTotal += message.Price; | |
await RequestTimeout(context, TimeSpan.FromDays(14), new DecrementTwoWeekTotal { Amount = message.Price }); | |
await context.Send(new FulfillPurchase { UserId = message.UserId, ItemId = message.ItemId }); | |
} | |
else | |
{ | |
await context.Publish(new BalanceInsufficient { UserId = message.UserId, ItemId = message.ItemId }); | |
} | |
} | |
public Task Timeout(DecrementOneWeekTotal state, IMessageHandlerContext context) | |
{ | |
Data.OneWeekTotal -= state.Amount; | |
return Task.CompletedTask; | |
} | |
public Task Timeout(DecrementTwoWeekTotal state, IMessageHandlerContext context) | |
{ | |
Data.TwoWeekTotal -= state.Amount; | |
return Task.CompletedTask; | |
} | |
protected override void ConfigureHowToFindSaga(SagaPropertyMapper<State> mapper) | |
{ | |
mapper.ConfigureMapping<UserBecamePreferred>(m => m.UserId).ToSaga(s => s.UserId); | |
mapper.ConfigureMapping<UserBecameUnpreferred>(m => m.UserId).ToSaga(s => s.UserId); | |
mapper.ConfigureMapping<UdiCoinsPurchased>(m => m.UserId).ToSaga(s => s.UserId); | |
mapper.ConfigureMapping<BuyItem>(m => m.UserId).ToSaga(s => s.UserId); | |
} | |
public class State : ContainSagaData | |
{ | |
public Guid UserId { get; set; } | |
public bool IsPreferred { get; set; } | |
public int OneWeekTotal { get; set; } | |
public int TwoWeekTotal { get; set; } | |
public int Balance { get; set; } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment