Stateless是一个基于C#,建立状态机的简单库,最新版本支持.NET Core 1.0。其实现方式并非经过.NET Core,而是经过写入.NET Standard实现的。就像Android平台上API级别抽象出许多底层版本的Android,.NET Standard是一组全部.NET平台上都必须实现的API。微信
更令开发者高兴的是,Stateless 3.0基于.NET Standard 1.0编写,是一个被普遍使用和最具兼容性的标准版本,几乎能够运行在任何地方,从Windows平台上的.NET Framework、.NET Core到Mac,和Windows应用商店以及全部的移动平台。less
特征:函数
支持大多数标准状态机构造:spa
支持任何.NET类型(数字、字符串、枚举等)状态和触发器;.net
分层状态;3d
状态的进入/退出事件;code
Guard子句以支持条件转换;orm
内省。blog
与此同时,还提供一些有用的扩展:接口
支持外部的状态存储(例如:由ORM跟踪属性);
参数化触发器;
可重入状态;
支持DOT格式图导出。
使用Stateless建立一个简单的状态机
下面来看几个代码示例。先描述一些有限状态,例如一个枚举类型和一些用于改变状态的有限“触发器”,就像开发同样,来启动和关闭状态以及进行触发器切换。
另外一个更加实用的例子是Bug Tracker,源码在GitHub上。下面是一个Bug和触发器状态,引发状态改变:
enum State { Open, Assigned, Deferred, Resolved, Closed }enum Trigger { Assign, Defer, Resolve, Close }
下面进行状态初始化,定义StateMachine,若是你愿意,能够在状态触发时传递参数。例如,若是你使用Assign触发Bug,能够传入“Scott”,这样该Bug就会进入Assigned状态——分配给Scott。
State _state = State.Open;
StateMachine<State, Trigger> _machine;
StateMachine<State, Trigger>.TriggerWithParameters<string> _assignTrigger;string _title;string _assignee;
在这个例子中,Bug构造函数使用一个流畅接口的状态机,该接口读得至关不错。
public Bug(string title)
{
_title = title;
_machine = new StateMachine<State, Trigger>(() => _state, s => _state = s); _assignTrigger = _machine.SetTriggerParameters<string>(Trigger.Assign); _machine.Configure(State.Open) .Permit(Trigger.Assign, State.Assigned);
_machine.Configure(State.Assigned) .SubstateOf(State.Open) .OnEntryFrom(_assignTrigger, assignee => OnAssigned(assignee)) .PermitReentry(Trigger.Assign) .Permit(Trigger.Close, State.Closed) .Permit(Trigger.Defer, State.Deferred) .OnExit(() => OnDeassigned());
_machine.Configure(State.Deferred) .OnEntry(() => _assignee = null) .Permit(Trigger.Assign, State.Assigned); }
例如,当状态打开时,能够进行分配,可是,因为它是被写入的(你能够改变),因此你没法关闭一个处于开放状态而且没有分配的Bug。
当Bug被分配时,你能够关闭,延迟或从新分配。这是PermitReentry()。另外,注意一下,Assigned是一个子状态。
你能够有状态地改变触发事件,这些事件能够根据您的我的设置采起行动。
void OnAssigned(string assignee)
{ if (_assignee != null && assignee != _assignee)
SendEmailToAssignee("Don't forget to help the new employee.");
_assignee = assignee;
SendEmailToAssignee("You own it.");
}void OnDeassigned()
{
SendEmailToAssignee("You're off the hook.");
}void SendEmailToAssignee(string message)
{
Console.WriteLine("{0}, RE {1}: {2}", _assignee, _title, message);
}
拥有一个好的状态机库,例如Stateless,可让你快速地模拟状态。可否分享一下,你在项目中使用的状态机是什么样子的?
原文地址: http://www.hanselman.com/blog/Stateless30AStateMachineLibraryForNETCore.aspx
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
本文分享自微信公众号 - dotNET跨平台(opendotnet)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。