public async Task Consume(ConsumeContext <OrderSubmittedEvent> context)
        {
            this.CustomerName        = context.Message.CustomerName;
            this.CoffeeTypeRequested = context.Message.CoffeeType;
            this.ToppingsRequested   = string.Join(",", context.Message.Toppings);
            this.Amount = CoffeePriceCalculator.Compute(context.Message.CoffeeType, context.Message.Toppings);
            var sendEndpoint = await context.GetSendEndpoint(requestPaymentEndpoint);

            await sendEndpoint.Send <RequestPaymentCommand>(new { this.CorrelationId, this.Amount });

            this.State = "AwaitingPayment";
        }
        public CoffeeStateMachine()
        {
            var requestPaymentEndpoint   = new Uri($"queue:{KebabCaseEndpointNameFormatter.Instance.SanitizeName(nameof(RequestPaymentCommand))}");
            var createBaseCoffeeEndpoint = new Uri($"queue:{KebabCaseEndpointNameFormatter.Instance.SanitizeName(nameof(CreateBaseCoffeeCommand))}");
            var addToppingsEndpoint      = new Uri($"queue:{KebabCaseEndpointNameFormatter.Instance.SanitizeName(nameof(AddToppingsCommand))}");


            Event(() => OrderSubmittedEvent, x => x.CorrelateById(context => context.Message.CorrelationId).SelectId(context => context.Message.CorrelationId));
            Event(() => PaymentAcceptedEvent, x => x.CorrelateById(context => context.Message.CorrelationId));
            Event(() => PaymentRefusedEvent, x => x.CorrelateById(context => context.Message.CorrelationId));
            Event(() => BaseCoffeeFinishedEvent, x => x.CorrelateById(context => context.Message.CorrelationId));
            Event(() => ToppingsAddedEvent, x => x.CorrelateById(context => context.Message.CorrelationId));

            InstanceState(x => x.CurrentState);

            Initially(When(OrderSubmittedEvent)
                      .Then(x =>
            {
                x.Instance.CustomerName        = x.Data.CustomerName;
                x.Instance.CoffeeTypeRequested = x.Data.CoffeeType;
                x.Instance.ToppingsRequested   = string.Join(",", x.Data.Toppings);
                x.Instance.Amount = CoffeePriceCalculator.Compute(x.Data.CoffeeType, x.Data.Toppings);
            })
                      .SendAsync(requestPaymentEndpoint, context => context.Init <RequestPaymentCommand>(new { context.Instance.CorrelationId, context.Instance.Amount }))
                      .TransitionTo(AwaitingPayment),
                      Ignore(PaymentAcceptedEvent));

            During(AwaitingPayment,
                   When(PaymentAcceptedEvent)
                   .SendAsync(createBaseCoffeeEndpoint, context => context.Init <CreateBaseCoffeeCommand>(new { context.Instance.CorrelationId, CoffeeType = context.Instance.CoffeeTypeRequested, NoTopping = string.IsNullOrWhiteSpace(context.Instance.ToppingsRequested) }))
                   .TransitionTo(Paid),
                   When(PaymentRefusedEvent)
                   .SendAsync(requestPaymentEndpoint, context => context.Init <RequestPaymentCommand>(new { context.Instance.CorrelationId, context.Instance.Amount })));

            During(Paid, When(BaseCoffeeFinishedEvent)
                   .IfElse(context => !string.IsNullOrWhiteSpace(context.Instance.ToppingsRequested), x => x
                           .SendAsync(addToppingsEndpoint, context => context.Init <AddToppingsCommand>(new { context.Instance.CorrelationId, Toppings = context.Instance.ToppingsRequested.Split(",").Select(t => Enum.Parse <Topping>(t)) }))
                           .TransitionTo(BaseCoffeeOK),
                           x => x.Finalize()));

            During(BaseCoffeeOK, When(ToppingsAddedEvent)
                   .Finalize());
        }