Simple But Nice State Machine

As part of something that I was messing around with the other day I wanted to use a state machine, so decided to have a quick hunt around before reinventing the wheel. My search yielded a few interesting things, namely the following:

BBV Common : This is a pretty neat library for .NET which includes the following components to name a few

StateMachine

BootStrapper

EvaluationEngine

EventBroker

Stateless : This is a very easy to use state machine by Nicholas Blumhardt who is also responsible for AutoFac which is a very nice IOC Container. Nick also worked on MEF, so I think it is fair to say Nick knows his onions.

I opted for using Stateless for what I wanted to do, the documentation is pretty good and comes with a few samples. But for the sake of completeness lets go through a simple example now shall we.

Suppose we have a state machine that looks something like this

It is a simple state machine that actually models our JIRA work flow at work. So how might I implement that using Stateless? Well it is actually pretty easy, all we need to do is carry out few steps

1. Create A State Machine

StateMachine<state, Trigger>

This allows us to create a StateMachine which will use a State object for its states, and a a Trigger for its triggers

The really nice thing about Stateless is that it allows you to create your own State types and trigger types. So we are free to create
our own state types, such as the following

public class State
{
public string Name { get; private set; }
///
/// Stateless has OnEntry/OnExit actions that can be run, but this just illustrates how you
/// could go about creating your own states that run their own actions where good encapsulation is
/// observed
///
public Action OnEntryStateAction { get; private set; }
///
/// Stateless has OnEntry/OnExit actions that can be run, but this just illustrates how you
/// could go about creating your own states that run their own actions where good encapsulation is
/// observed
///
public Action OnExitStateAction { get; private set; }
public State(string name, Action onEntryStateAction, Action onExitStateAction)
{
Name = name;
OnEntryStateAction = onEntryStateAction;
OnExitStateAction = onExitStateAction;
}
}

2. Define some triggers

This can be any type you want, I opted for enum values, so for my example this look like this

3.3 Firing Triggers

Once you have your state machine setup you can simply fire triggers to transition from one state to another

Here is an example of that

Fire(jiraMachine, Trigger.StartDevelopment);

So I think that covers the basics, I think it’s time to see a fuller example, so lets look at a little sample. This sample follows the state machine diagram above. I have included one small imbellishment, which is a tiny bit of Reactive Extensions (Rx) to have a certain action performed (ok its a simple Console.Writeline but it could be anything you want) when you are within the “InDevelopment” state.

By using Rx we can simply Dispose of the IObservable subscription when we exit the state, which I think is nice

The simplicity and usability of Stateless is great. Inspired by it, we developed a workflow engine with a SQL back-end supporting storing configurations(state/action), transitions, mail templates, audit, escalations, user permissions and other features.