Stateless 3.0——.NET Core上的状态机库

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源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索