.Net 状态机Stateless

Stateless 库中,可以通过配置来获取状态(State)、触发器(Trigger)以及目标状态(Destination State)。以下是如何进行配置的详细说明:

1. 创建状态机

首先,你需要创建一个状态机实例。状态机实例需要指定当前状态和触发器类型。例如:

var phoneCall = new StateMachine<State, Trigger>(State.OffHook);

CopyInsert

在这个例子中,StateTrigger 是枚举类型,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

在这个例子中,OnHoldConnected 状态的初始子状态。

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 是一个布尔函数,用于决定是否允许转换。

posted @ 2024-09-14 10:50  猿锋博客  阅读(26)  评论(0编辑  收藏  举报