1.6 The train
Trains/PlaceOrder/IPlaceOrderTrain.cs:
using Trax.Effect.Services.ServiceTrain;
namespace Shopfront.Trains.PlaceOrder;
public interface IPlaceOrderTrain : IServiceTrain<PlaceOrderInput, PlaceOrderOutput>;Trains/PlaceOrder/PlaceOrderTrain.cs:
using Shopfront.Trains.PlaceOrder.Junctions;
using Trax.Core.Functional;
using Trax.Effect.Services.ServiceTrain;
namespace Shopfront.Trains.PlaceOrder;
public class PlaceOrderTrain : ServiceTrain<PlaceOrderInput, PlaceOrderOutput>, IPlaceOrderTrain
{
protected override Task<Either<Exception, PlaceOrderOutput>> Junctions() =>
Chain<PriceCartJunction>()
.Chain<ReserveStockJunction>()
.Chain<TakePaymentJunction>()
.Chain<ConfirmOrderJunction>()
.Resolve();
}The train is only the order of its junctions. Nothing here passes a value from one junction to the
next: the train carries a store called Memory, which holds the input when the train starts and
each junction's output as it finishes, one value per type. Every junction takes its input from
there. That is how TakePaymentJunction gets the PlaceOrderInput even though the junction just
before it made a StockReservation. One value per type also means a junction that returns a type
already in Memory replaces the value there, which is why each junction here returns a type of its
own (Memory).
Nothing reads the StockReservation yet. In chapter 3 the payment starts failing, and
TakePaymentJunction takes the reservation too, to give the stock back before the order stops.
IPlaceOrderTrain is how the rest of the application asks for the train, and its full name is the
name Trax records each run under.
SDK Reference
Junctions | Chain | Run / RunEither | TrainException | AddTrax / AddEffects | UseInMemory | SaveTrainParameters | AddMediator
Next: 1.7 Run it