/
OrderStateMachine.cs
95 lines (85 loc) · 4 KB
/
OrderStateMachine.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
namespace Sample.Components.StateMachines
{
using System;
using System.Linq;
using Automatonymous;
using Contracts;
using MassTransit;
using OrderStateMachineActivities;
public class OrderStateMachine :
MassTransitStateMachine<OrderState>
{
public OrderStateMachine()
{
Event(() => OrderSubmitted, x => x.CorrelateById(m => m.Message.OrderId));
Event(() => OrderAccepted, x => x.CorrelateById(m => m.Message.OrderId));
Event(() => FulfillmentCompleted, x => x.CorrelateById(m => m.Message.OrderId));
Event(() => FulfillmentFaulted, x => x.CorrelateById(m => m.Message.OrderId));
Event(() => FulfillOrderFaulted, x=>x.CorrelateById(m => m.Message.Message.OrderId));
Event(() => OrderStatusRequested, x =>
{
x.CorrelateById(m => m.Message.OrderId);
x.OnMissingInstance(m => m.ExecuteAsync(async context =>
{
if (context.RequestId.HasValue)
{
await context.RespondAsync<OrderNotFound>(new {context.Message.OrderId});
}
}));
});
Event(() => AccountClosed, x => x.CorrelateBy((saga, context) => saga.CustomerNumber == context.Message.CustomerNumber));
InstanceState(x => x.CurrentState);
Initially(
When(OrderSubmitted)
.Then(context =>
{
context.Instance.SubmitDate = context.Data.Timestamp;
context.Instance.CustomerNumber = context.Data.CustomerNumber;
context.Instance.PaymentCardNumber = context.Data.PaymentCardNumber;
context.Instance.Updated = DateTime.UtcNow;
})
.TransitionTo(Submitted));
During(Submitted,
Ignore(OrderSubmitted),
When(AccountClosed)
.TransitionTo(Canceled),
When(OrderAccepted)
.Activity(x => x.OfType<AcceptOrderActivity>())
.TransitionTo(Accepted));
During(Accepted,
When(FulfillOrderFaulted)
.Then(context => Console.WriteLine("Fulfill Order Faulted: {0}", context.Data.Exceptions.FirstOrDefault()?.Message))
.TransitionTo(Faulted),
When(FulfillmentFaulted)
.TransitionTo(Faulted),
When(FulfillmentCompleted)
.TransitionTo(Completed));
DuringAny(
When(OrderSubmitted)
.Then(context =>
{
context.Instance.SubmitDate ??= context.Data.Timestamp;
context.Instance.CustomerNumber ??= context.Data.CustomerNumber;
}),
When(OrderStatusRequested)
.RespondAsync(x => x.Init<OrderStatus>(new
{
OrderId = x.Instance.CorrelationId,
State = x.Instance.CurrentState
}))
);
}
public State Submitted { get; private set; }
public State Accepted { get; private set; }
public State Canceled { get; private set; }
public State Faulted { get; private set; }
public State Completed { get; private set; }
public Event<OrderSubmitted> OrderSubmitted { get; private set; }
public Event<OrderAccepted> OrderAccepted { get; private set; }
public Event<OrderFulfillmentCompleted> FulfillmentCompleted { get; private set; }
public Event<OrderFulfillmentFaulted> FulfillmentFaulted { get; private set; }
public Event<CheckOrder> OrderStatusRequested { get; private set; }
public Event<CustomerAccountClosed> AccountClosed { get; private set; }
public Event<Fault<FulfillOrder>> FulfillOrderFaulted { get; private set; }
}
}