Creating a State Machine in Code

Lots of people create state machines.  There are many examples on the web of people who are building class libraries to make it easy to create a state machine.  These people typically don’t need (or want) to use a workflow designer or see a state diagram they simply want to write a state machine in code.

What if you could create a Windows Workflow Foundation State Machine in code?

Yes, you can create a WF4 state machine in code today.  However, if you have ever tried to create any workflow in code you find our right away that it can be a bit tricky.  You have to learn quite a bit about WF4 concepts like InArgument<T>, Variable<T>, ArgumentReference, VariableReference, VisualBasicValue etc.

The more we thought about this space the more we realized that a developer who simply wants to write code and does not need to support a workflow designer experience probably doesn’t need to use any of these things.

The idea is really very simple.  Make it possible for a developer to implement a state machine workflow using familiar language concepts like Task<T>, Action<T> or Func<T> with a simple fluent interface for creating the workflow.

Under the covers the API would construct a workflow that is run by Windows Workflow Foundation so it can take advantage of tracking, persistence and even leverage existing activities if you want to – but you don’t have to do any of these things.

I’ve written enough of a prototype to know that this can be done.  Now I want to get your input.  After all, I could spend a lot of time building something that nobody cares about.  I don’t want to over engineer this thing and I want to get it simple enough so that someone with absolutely no WF experience could in less than an hour create and run a simple state machine.

Prototype Code

This prototype code is creating the state machine activity that you build in exercise 1 of the Introduction to State Machine Hands on Lab.  For a prototype I wanted to see how it would feel to use an alternate code based API with no workflow concepts at all.

Download the prototype code here

 private StateMachine<AtmState, AtmTrigger> CreateStateMachine()
 {
     // Fluent interface for declaring the state machine
     // Enums define the states and transitions
     this.atmStateMachine = new StateMachine<AtmState, AtmTrigger> { DisplayName = "ATM StateMachine" };
  
     // Use an indexer to refer to the state you want
     // Non workflow developers can use lambda expressions or Action to provide implementation - no need to learn WF
     // AutoTrigger is a null transition
     this.atmStateMachine[AtmState.Initialized]
         .Entry(this.Prompt, Activities.Prompts.PleaseWait)
         .Exit(this.ClearView)
         .AutoTrigger(AtmState.InsertCard);
  
     // When defines a transition that is implemented with a bookmark
     this.atmStateMachine[AtmState.InsertCard]
         .Entry(this.Prompt, Activities.Prompts.InsertCard)
         .When(AtmTrigger.PowerOff, AtmState.PowerOff);
  
     this.atmStateMachine[AtmState.PowerOff]
         .Entry(this.ClearView);
  
     return this.atmStateMachine;
 }

How you can help

Take a look at the Microsoft.Activities.StateMachine project page and leave a comment or vote for this issue and leave a comment to tell us why you care about this.

Happy Coding!

Ron Jacobs

https://blogs.msdn.com/rjacobs

Twitter: @ronljacobs https://twitter.com/ronljacobs