1.3 The shop
Before any Trax code, the shop needs something to sell and a way to be paid. Both are plain classes.
Inventory/Catalogue.cs:
namespace Shopfront.Inventory;
// The catalogue and its stock, in memory for now.
public class Catalogue
{
private readonly Dictionary<string, (decimal Price, int Stock)> items = new()
{
["MUG"] = (12.00m, 10),
["TEE"] = (25.00m, 3),
["CAP"] = (18.50m, 0),
};
public decimal? PriceOf(string sku) => items.TryGetValue(sku, out var item) ? item.Price : null;
// Reserves every line or none of them. Returns the first SKU that is short, or null.
public string? TryReserve(IReadOnlyList<(string Sku, int Quantity)> lines)
{
lock (items)
{
var shortSku = lines
.Where(l => items[l.Sku].Stock < l.Quantity)
.Select(l => l.Sku)
.FirstOrDefault();
if (shortSku is not null)
return shortSku;
foreach (var (sku, quantity) in lines)
items[sku] = items[sku] with { Stock = items[sku].Stock - quantity };
return null;
}
}
}The caps are out of stock on purpose. We will try to buy one.
Payments/IPaymentProvider.cs:
namespace Shopfront.Payments;
public interface IPaymentProvider
{
Task<string> Charge(string customerId, decimal amount, CancellationToken cancellationToken);
}Payments/FakePaymentProvider.cs:
namespace Shopfront.Payments;
// Always succeeds. Chapter 2 makes it fail.
public class FakePaymentProvider : IPaymentProvider
{
public Task<string> Charge(
string customerId,
decimal amount,
CancellationToken cancellationToken
) => Task.FromResult($"tx_{Guid.NewGuid():N}"[..11]);
}SDK Reference
Junctions | Chain | Run / RunEither | TrainException | AddTrax / AddEffects | UseInMemory | SaveTrainParameters | AddMediator