StateMachine
3.0.0 页面说明
- 3.0.0 说明:当前页已重写为
3.x的状态机主题页。- 当前组件入口: Aegis.Toolkit.StateMachine。
StateMachine 适合把复杂状态流转从普通业务代码里拆出来。它尤其适合订单、审核、锁状态、流程状态这类“有限状态 + 明确转移规则”的场景。
推荐接入路径
第一步:启用组件
{
"Components": {
"Services": [
"Toolkit.StateMachine"
],
"Middlewares": []
}
}
第二步:定义状态枚举
public enum OrderState
{
Pending,
Processing,
Completed,
Cancelled
}
第三步:定义状态上下文
public class OrderContext : StateContext<OrderState>
{
public int OrderId { get; set; }
}
第四步:定义状态流转规则
var transitions = new Dictionary<OrderState, OrderState[]>
{
{ OrderState.Pending, new[] { OrderState.Processing, OrderState.Cancelled } },
{ OrderState.Processing, new[] { OrderState.Completed } }
};
var validator = new StateValidator<OrderState>(
transitions,
new[] { OrderState.Pending });
第五步:定义状态处理器
public class ProcessingHandler : IStateHandler<OrderState, OrderContext>
{
public OrderState State => OrderState.Processing;
public ApplyStateResult CanTransition(OrderContext context, OrderState? newState)
{
return new ApplyStateResult
{
IsSuccess = true,
Code = 200,
Message = "OK"
};
}
public void Enter(OrderContext context, OrderState? oldState)
{
}
public void Exit(OrderContext context)
{
}
}
第六步:定义业务状态机
public class OrderStateMachine : BaseStateMachine<OrderState, OrderContext>
{
public OrderStateMachine(
StateValidator<OrderState> validator,
StateHandlerManager<OrderState, OrderContext> stateHandlerManager)
: base(validator, stateHandlerManager)
{
}
protected override Task<bool> PersistStateAsync(OrderContext context)
{
return Task.FromResult(true);
}
}
第七步:执行状态变更
var context = new OrderContext
{
CurrentState = OrderState.Pending,
OrderId = 1001
};
await stateMachine.ApplyStateAsync(context, OrderState.Processing);
应该怎么理解这几层
StateValidator<TState>:负责“能不能转”IStateHandler<TState, TContext>:负责“转之前和转之后做什么”BaseStateMachine<TState, TContext>:负责“按统一流程组织起来”PersistStateAsync(...):负责“最终怎么保存状态”
最容易踩坑的地方
当前处理器接口是双泛型
业务处理器应该实现:
IStateHandler<TState, TContext>
不要按旧写法写成单泛型版本。
状态机不会替你自动落库
真正的状态保存逻辑,还是要写在你自己的 PersistStateAsync(...) 里。
更推荐在 Services 层调用状态机
状态机负责规则,Service 负责业务时机。
这样职责会更清楚。
常见问题
为什么状态切换失败了
优先检查:
- 当前状态能不能转到目标状态
- 处理器的
CanTransition(...)是否放行 PersistStateAsync(...)是否返回成功
状态处理器里适合放什么
适合放和状态强绑定的进入、退出、副作用逻辑。
不适合把整个业务流程都塞进去。
状态机该不该替代 Service
不该。
状态机是业务规则工具,不是业务层替代品。