Creating State Machine Workflows – Step by Step Windows Application – Part I
A state machine workflow is all about different states a program execution is in. Take for example Ordering a coffee at a restaurant. How it will go:
1. You order for coffee.
2. Coffee is getting prepared
3. Coffee is delivered
Now think of the above steps as a states in .NET Workflow world and guess what you have just completed is the first step in your state machine workflows. The first step of State Machine says identify your real world problem in terms of states and human interventions.
Let’s examine each step in a bit detail: The coffee maker is Waiting for Order (State), your Order is received (Event), he prepares coffee (State), once he is done, he says to the waiter that coffee is prepared (Event), the waiter lifts the coffee and delivers at your table(State), you drink it(Completed). So the story board is pretty clear, identify your states and the events which will takes those states to the next state.
Now let’s design a workflow based on the above story board.
The above State Machine depicts what we just discussed.
How to do:
- Open Visual Studio.
- Start a new project à Workflow àState Machine Console Application
- Once your State Machine Canvas is set, drag and drop 4 State Activity on it.
- In each activity drag and drop one EventDriven Activity.
- Name the States as given in the picture by setting (Name) property for each activity.
- Same way name the EventDriven Activity by setting (Name) property for each activity.
Now we have plotted our story line in terms of a State Machine Workflow diagram.
Now how do we make it work?
Concepts:
States represents a State your program is in at any given point of time.
EventDriven Activity enables execution of the contained activities based on some event.
So our first task is to define what all events we can handle. For this purpose we will go with an interface to define all the events which our workflow can handle.
[ExternalDataExchange]
public interface IOrderSystem
{
event EventHandler<OrderEventArgs> OrderReceived;
event EventHandler<OrderEventArgs> OrderProcessed;
event EventHandler<OrderEventArgs> GoodsDelivered;
}
So here is our interface.
Notice the details…in our workflow we have only three events so our interface also defines that we can handle only 3 events.
Attribute [ExternalDataExchange] marks the interface to be used for the purpose of handling external data. In this way we say that this interface defines the contract between the Workflow and any external entity. If the external entity has to send any events it has to be one of these only. The good question is how the external entity sends an event using this interface? For that we need to implement this interface, so that the external entity can actually instantiate that class in order to send events to the workflow.
public class OrderSystem: IOrderSystem
{
public event EventHandler<OrderEventArgs> OrderReceived;
public event EventHandler<OrderEventArgs> OrderProcessed;
public event EventHandler<OrderEventArgs> GoodsDelivered;
public void OnOrderReceived(OrderEventArgs e)
{
if (OrderReceived != null)
{
this.OrderReceived(null, e);
}
}
public void OnOrderProcessed(OrderEventArgs e)
{
if (OrderProcessed != null)
{
this.OrderProcessed(null, e);
}
}
public void OnGoodsDelivered(OrderEventArgs e)
{
if (GoodsDelivered != null)
{
this.GoodsDelivered(null, e);
}
}
}
Now we have implemented this as well. One more thing remaining is have you noticed OrderEventArgs? Yes it’s a custom EventArg to send some event info to the workflow. What we send is the OrderNumber just for the demo purposes.
[Serializable]
public class OrderEventArgs: ExternalDataEventArgs
{
private int orderNumber;
public OrderEventArgs(Guid instanceId, int orderNumber): base (instanceId)
{
this.orderNumber = orderNumber;
}
}
Remember it must extend ExternalDataEventArgs and must be Serializable.
Now we have everything in place, let’s go back to our workflow diagram to complete it.
What do need to complete? We have to make each state transit in to the next state.
How to do:
1. Double click on your first eventDriven activity: OrderReceived
2. Drag and drop a handleExternalEvent Activity.
3. In the InterfaceType property select our IOrderSystem interface.
4. The EventType property now will list all the Events available in this interface. Select the OrderReceived Event
5. Drag and drop a SetState activity.
6. Set TargetStateName property to next state that is ProcessingOrder (this should be available in the dropdown)
7. Similarly do for all other EventDriven activity as well.
8. Notice when you come back to you main workflow you will see a connecting line between your states. This comes because of SetState Activity’s TargetStateName Property.
Once you reach GoodsDelivered eventdriven activity, you are done with your StateMachine workflow.
Go ahead and compile it.
Your first part of this mission is accomplished. For the second part of how to host this in a Windows application, keep watching this space for Part II of this article.




