Ron Jacobs

Windows Workflow Foundation

Creating a State Machine in Code

Creating a State Machine in Code

  • Comments 4

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
http://blogs.msdn.com/rjacobs
Twitter: @ronljacobs http://twitter.com/ronljacobs

  • Nicolas Blumhardt - creator of AutoFac - has a very similar concept for a simple state machine called Stateless.  Here is the project page:  code.google.com/.../stateless.  The beauty of what Nicolas has written is that the state of the state machine can be represented as an integer, string, enum, whatever.  Very simple to process and store in a database.  Using this technique I have been able to create robust workflows without having to worry about persisting the workflow and I can execute in a sinlge thread in ASP.Net.

    I like the concept that you are pursuing, as it masks the complexity of WF4.  Many times people shy away from WF4 because of its complexity, but with the direction you are taking things would be much simpler and focus on testing and validation of the business process.  

  • Ron, I definately want to take a depp look at what you have done, it can address many needs. On the other hand (isnt there always another hand??) alot of times I use a workflow (sequential or state machine) simply because I want (almost "need") the visualization and the ability for someone else to "tweak" the workflow (especially in the face of eventual gchanging requirements. The visual aspect is (for these cases) a key driving aspect of selecting WF in the first place.

    What I would *REALLY* love to see is a way to create the WF in code, but in a manner that could be "run through a process" that allowed it to be visualized and have the editing capabilities of the "GUI".

    David

  • As you can see in the source unit tests, you can export the code created workflow to XAML.  However right now I'm using things that cannot be visualized in the designer.

    Then once you open it in the designer and make changes there is no way to get it back to the code format.  There are many challenges to getting round tripping to work correctly.  For now I'm just focused on a great code based experience.

  • A lot of appeal over the UI-centric approach. What are the major hurdles to round-tripping between the two methods? Can/could we hope to see improvements for David Corbin's scenario?

Page 1 of 1 (4 items)