.Net 状态机Stateless
在 Stateless
库中,可以通过配置来获取状态(State)、触发器(Trigger)以及目标状态(Destination State)。以下是如何进行配置的详细说明:
1. 创建状态机
首先,你需要创建一个状态机实例。状态机实例需要指定当前状态和触发器类型。例如:
var phoneCall = new StateMachine<State, Trigger>(State.OffHook);
CopyInsert
在这个例子中,State
和 Trigger
是枚举类型,State.OffHook
是初始状态。
2. 配置状态和触发器
接下来,你可以配置每个状态的行为,包括允许的触发器和目标状态。例如:
phoneCall.Configure(State.OffHook)
.Permit(Trigger.CallDialed, State.Ringing);
CopyInsert
在这个例子中,当状态为 OffHook
时,触发器 CallDialed
会将状态转换为 Ringing
。
3. 获取当前状态和允许的触发器
你可以通过 StateMachine.State
属性获取当前状态,并通过 StateMachine.PermittedTriggers
属性获取当前状态下允许的触发器。例如:
State currentState = phoneCall.State;
IEnumerable<Trigger> allowedTriggers = phoneCall.PermittedTriggers;
CopyInsert
4. 触发状态转换
你可以通过 Fire
方法触发状态转换。例如:
phoneCall.Fire(Trigger.CallDialed);
CopyInsert
这将触发状态从 OffHook
转换到 Ringing
。
5. 配置子状态和初始状态
如果你有子状态,可以通过 InitialTransition
方法配置初始子状态。例如:
phoneCall.Configure(State.Connected)
.InitialTransition(State.OnHold);
CopyInsert
在这个例子中,OnHold
是 Connected
状态的初始子状态。
6. 异步触发器
如果你需要处理异步操作,可以使用 FireAsync
方法。例如:
await phoneCall.FireAsync(Trigger.CallDialed);
CopyInsert
7. 导出状态机图
你可以将状态机导出为 DOT 图格式,以便可视化。例如:
string dotGraph = UmlDotGraph.Format(phoneCall.GetInfo());
CopyInsert
这个字符串可以被渲染为图像,例如使用 Graphviz 工具。
8. 外部状态存储
如果你需要将状态存储在外部对象中,可以在创建状态机时传递读写状态的委托。例如:
var stateMachine = new StateMachine<State, Trigger>(
() => myState.Value,
s => myState.Value = s);
CopyInsert
在这个例子中,myState
是一个包含状态值的对象。
9. 事件通知
你可以订阅状态转换事件,以便在状态转换时执行特定操作。例如:
phoneCall.OnTransitioned(t => Console.WriteLine($"Transitioned from {t.Source} to {t.Destination}"));
CopyInsert
10. 保护子句
你可以使用保护子句来决定在多个可能的转换中选择哪一个。例如:
phoneCall.Configure(State.OffHook)
.PermitIf(Trigger.CallDialed, State.Ringing, () => IsValidNumber);
CopyInsert
在这个例子中,IsValidNumber
是一个布尔函数,用于决定是否允许转换。