介绍
Automatonymous是.NET开发人员的状态机库。它提供了一种流畅的语法来声明状态机,包括状态,事件(支持触发器和数据事件)以及状态/事件活动。尽管Automatonymous在简单的状态机上非常容易使用,但它具有许多高级功能,使它可以在各种上下文中使用。
快速入门
跟随官网提供的快速入门demo,定义了一个关系状态机,关系状态有两种:Friend(朋友-友好)、Enemy(敌人-敌意),三个可以引发的事件:Hello(打招呼)、PissOff(走开)、Introduce(自我介绍)。打招呼->友好、走开->敌意、自我介绍->友好状态。
创建一个控制台应用程序,然后安装Automatonymous
我们创建两个类,一个类表示状态(Relationship),另一个类定义状态的行为(RelationshipStateMachine),代码如下:
代码语言:javascript复制 /// <summary>
/// 状态类
/// </summary>
public class Relationship
{
public State CurrentState { get; set; }
public string Name { get; set; }
}
/// <summary>
/// 状态机
/// </summary>
public class RelationshipStateMachine :
AutomatonymousStateMachine<Relationship>
{
public State Friend { get; private set; }
public State Enemy { get; private set; }
public Event Hello { get; private set; }
public Event PissOff { get; private set; }
public Event<Person> Introduce { get; private set; }
public RelationshipStateMachine()
{
//定义当前 状态属性
InstanceState(x => x.CurrentState);
//定义事件
Event(() => Hello);
Event(() => PissOff);
Event(() => Introduce);
// 定义状态
State(() => Friend);
State(() => Enemy);
Initially(
When(Hello)
.Then(p => Console.WriteLine("StateMachine: Hello"))
.TransitionTo(Friend),
When(PissOff)
.Then(ctx => Console.WriteLine(ctx.Instance.CurrentState.Name))
.TransitionTo(Enemy),
When(Introduce)
.Then(p =>
{
p.Instance.Name = p.Data.Name;
Console.WriteLine($"你好:{p.Instance.Name},这是状态机简单入门篇");
})
.TransitionTo(Friend).Finalize()
);
}
}
/// <summary>
/// 事件数据
/// </summary>
public class Person
{
public string Name { get; set; }
}
小结:在Automatonymous中 ,状态是使用类进行管理的,如上面的Relationship。状态机行为类定义需要继承行为类需要继续AutomatonymousStateMachine类,它是泛型类,需指定与行为关联的状态类型如AutomatonymousStateMachine<Relationship>。默认情况下,事件或状态的所有公共属性都将在基类的构造函数中自动定义和初始化。在构造函数中使用lambda方法Event和state方法明确地定义事件和状态。
客户端引发事件
支持事件无数据和有数据两种方式,代码如下:
代码语言:javascript复制static void Main(string[] args)
{
var relationship = new Relationship();
var machine = new RelationshipStateMachine();
//machine.RaiseEvent(relationship, machine.Hello); 无数据
var person = new Person { Name = "知音" };
machine.RaiseEvent(relationship, machine.Introduce, person);//指定事件需要的数据
}
输出
我们知道Saga也是解决分布式事务一种方案,其中MassTransit提供的Sagas功能以及事件驱动的状态机就是利用的Automatonymous。这个作者很厉害我的偶像,Topshelf也是出自他之手,值得学习。