Click here to Skip to main content
15,867,141 members
Articles / Web Development / ASP.NET

State Machine Workflow Discussion

Rate me:
Please Sign up or sign in to vote.
5.00/5 (32 votes)
26 Jun 2009CPOL11 min read 112.6K   2.3K   75   13
A State Machine Workflow discussion.

Contents

Other FAQs

  • Silverlight FAQ Part 1: Click here
  • Silverlight FAQ Part 2: Click here
  • Silverlight FAQ Part 3: Click here

Introduction

All characters in this article are fictional and any resemblance to anyone live or dead is purely coincidental.

This is a nice talk between Mr. RC and Mr. Shiv about state machine workflows. RC starts talking about an order project and they end up in a nice discussion which gives us a step by step approach of how to execute a state machine workflow.

This article was written in a straight half an hour session so please excuse my English as it’s my second language and any spelling mistakes. So guys. enjoy state machines.

The State Machine Workflow discussion

Ramprasad Chaurasiya: Hi Shiv, how’s things?

Shivprasad Koirala: Doing great RC (Ramprasad Chaurasiya).

RC: You have written more than 60 articles, that’s huge; looks like you are copy pasting articles from MSDN and other sources.

Shiv: Hmmm, can we talk something better before you reveal me completely :) ?

RC: I was reading your article on WWF: WWF.aspx. I am working currently on an order processing project and I am a bit confused about how the workflow aspect of the project should be approached.

Shiv: Can you explain to me the workflow part of your order project?

RC: OK, here’s the requirement for the order and I have drawn a small sketch of how the workflow looks like:

  • The workflow starts by the user placing an order.
  • The accounts department logs in and checks if the payment is made for the order. If the payment is not made, then they mark the order as cancelled and it’s sent to the user for payment.
  • Once the user makes the payment, the order is moved to a valid order placed on stage again.
  • Purchase department logs in and checks if the product is in stock for the order.
  • If the product is in stock, the purchase department person enters saying the product is in-stock and the order is then ready for dispatch.
  • Courier department logs in and checks if the address of the order is proper. If the address is not proper, the order is moved to a pending stage and sent to the end user for address correction.
  • In pending stage, if the user corrects the address, the order is then moved back to ready for dispatch.
  • If the order is dispatched and received by the end user, the delivery person marks the order as delivered.

Image 1

Shiv: Hmmm, it’s an interesting workflow. This can be very easily solved by using Windows Workflow Foundation. The first step we need to decide is which kind of workflow we need to choose for the above.

RC: Ohhh, are there different kinds of workflows in Windows Workflow Foundation?

Shiv: Primarily there are two kinds of workflow in WWF and depending on the nature of our requirements, we need to choose the workflow accordingly.

RC: That’s funny, I thought a workflow is just a collection of activities which are executed depending on certain conditions. For instance, the below figure shows a simple workflow which has customer activities, and some conditions depending on which the activities are executed. In other words, what I want to say is a workflow is work flow. What do you mean by types of workflow?

Image 2

Shiv: From the Windows Workflow Foundation point of view, there are two types of workflows: sequential workflow and state machine workflow.

A sequential workflow has clear start and finish boundaries. Workflow controls the execution in a sequential workflow. In sequential execution, one task is executed after another. Sequential workflow is more rigid in format and the execution path has a deterministic nature.

A State Machine workflow is more dynamic in nature. The workflow has states and the states wait for events to help it move to the next state. In a State Machine, the execution path is indeterministic in nature.

The below figure shows the visual conceptualization of the fundamentals. You can see that in sequential workflow, the execution path is very determent. Shiv performs the entire task sequentially and these tasks are very determent. Now have a look at the second workflow. Every state goes to another state when it receives external events. For instance, when Shiv is seeing Star Trek, there is an event of flashing news which triggers him to see the flashing news.

Image 3

RC: In other words, we can say that if the workflow controls the execution then it is sequential and if there is some external factor which controls the workflow, then it becomes a State Machine workflow.

Shiv: Yes, that’s a good summary. Looks like you have started thinking in terms of workflows. So now let’s first decide which kind of workflow your order project is.

RC (thinking): Well, I think it’s a sequential workflow as the workflow has control on the execution.

Shiv: OK, so let me redraw your workflow diagram. Below is your changed diagram. You can see there are so many inputs from the user which changes your workflow. For instance, the accounts department depending on the payment diverts the workflow, the purchase department depending on the stock value diverts the flow, and the same holds true for the courier person.

Image 4

RC: I understand where you are coming from. My workflow is not in control of itself. OK, I buy back my point that my order project is a State Machine workflow.

Shiv: A few comments on workflow types before we move ahead. Many architects get carried away with sequential workflows. If you see in your application that depending on user input your workflow is changing, then it’s a good idea to think about a State Machine. Let me comment from a more practical point of view. In actual projects, it’s a combination of these types rather than just one type. In other words, you can have a broader state machine workflow which has a lot of sequential workflows in between and vice versa.

RC: What I also think is we should also look from the domain perspective what kind of workflow it actually looks like. OK, this sounds good. How can we now move ahead?

Shiv: Let’s first try to visualize the important elements in a State Machine workflow. The three important things in a State Machine workflow are initial state, action, and final state. You can see from the figure a simple example of a State Machine. So you have an initial state, an action happens, and it moves to some other state. For instance, a bulb is first in on state and then switched off and it moves to off state.

Image 5

RC: OK, I am trying to get a feel of State Machines now.

Shiv: Let’s first visualize the whole order workflow from these three aspects. Below is a table which shows the whole workflow from the above three perspectives.

First state Action / Event Next state

Order placed

InStockEvent

Order approved

Order placed

NotPaidEvent

Order cancelled

Order cancelled

PaymentMadeEvent

Order placed

Order approved

AddressNotProperEvent

Order pending

Order pending

AddressCorrectedEvent

Order approved

Order approved

DispatchedEvent

Order delivered

RC: OK, that is a good visualization. What I understand is we have in all four different states and some 6 to 7 events. I think our State Machine diagram will look something like below:

Image 6

Shiv: Nice that you are catching up on State Machines. Now that we are clear about our states and our events, it’s time to make the complete workflow using WWF.

RC: That makes sense. I really do not like theory, there should be some practical implementation.

Shiv: We will be using VS 2008 Enterprise and .NET 3.5.

RC: Why not Express edition?

Shiv: Well, WWF does not come with an Express edition.

RC: OK, noted.

Shiv: Before we move ahead and talk about the practical implementation, there’s one more point we need to cover. In a typical workflow project, we have two important things: the workflow and the client which can be a Windows or web application which consumes that workflow. In a State Machine workflow, we need to define an interface with all actions. This interface is the only thing which the workflow knows. So any client who wants to invoke the workflow should make calls using this interface.

Image 7

RC: OK, got it, so this interface is the gateway to make calls to the workflow.

Shiv: Yes, you said it right. Below is our interface. The first step we need to do is create the interface. The below figure shows that we have created an IOrder.cs interface. The important point to note is we have referenced System.Workflow.Activities and attributed the interface with ExternalDataExchange. We have then defined all our events for the states in this interface.

Image 8

RC: That’s a pretty simple step.

Shiv: OK, now add a new project and select ‘State Machine Workflow Library’.

Image 9

Shiv: Once you create the workflow project, a workflow designer pops up as shown below. Every state in a workflow has events, so go to the workflow toolbox and drag and drop the event driven component on the state activity.

Image 10

RC: Hang on Shiv, correct me if I am wrong. As per our discussion, logically, every state should have events by which the state changes its action and it should also know which next state it should move to after the event.

Image 11

Shiv: You are absolutely right. Double click on the state and drag two things: a handle to the external event which defines which event it should listen to, and the set state which says which the next state it should move on to is.

Image 12

RC: OK great. So how should we define the events and the next state for the state?

Shiv: If you remember, we had defined an interface. It’s time to start using it. Go to the properties of the handle event and select the interface type and the event for it. The below figure shows the state is OrderPlaced and we need to handle the InStock event.

Image 13

Shiv: Now to specify the  next state, go to the property of the set state component and specify the target state name.

Image 14

Shiv: So create states, create an event we need to handle in the states, and the next state. You will see that you ended up in something like shown below.

Image 15

RC: The visuals look great and appealing.

Shiv: Yeah… The most important part for WWF is to get a feel of the workflow development.

RC: OK, this sounds good. What next?

Shiv: One of the most important points we have forgotten is we need to make our concrete class which will be called by the client. Let’s implement the interface IOrder. You can see the class clsOrder below which implements IOrder. We just display simple console messages. Remember, this concrete class will be called by the client and all the below methods of the class will be invoked by the client. This class internally calls the interface which in turn invokes the workflow engine.

C#
public class clsOrder : IOrder
{
#region IOrder Members
	public event EventHandler<ExternalDataEventArgs> NotPaid;
	public event EventHandler<ExternalDataEventArgs> InStock;
	public event EventHandler<ExternalDataEventArgs> PaymentMade;
	public event EventHandler<ExternalDataEventArgs> Dispatch;
	public event EventHandler<ExternalDataEventArgs> AddressNotProper;
	public event EventHandler<ExternalDataEventArgs> AddressCorrected;
	public event EventHandler<ExternalDataEventArgs> ProductStocked;
#endregion

	public void CallNotPaid(ExternalDataEventArgs args)
	{
		NotPaid(null, args);
		Console.WriteLine("This order is not paid");
	}

	public void CallInStock(ExternalDataEventArgs args)
	{
		InStock(null, args);
		Console.WriteLine("Product is InStock");
	}

	public void CallPaymentMade(ExternalDataEventArgs args)
	{
		PaymentMade(null, args);
		Console.WriteLine("Payment is made for this Order");
	}

	public void CallDispatch(ExternalDataEventArgs args)
	{
		Dispatch(null, args);
		Console.WriteLine("Dispatch the Order");
	}

	public void CallAddressNotProper(ExternalDataEventArgs args)
	{
		AddressNotProper(null, args);
		Console.WriteLine("Adress is not Proper");
	}

	public void CallAddressCorrected(ExternalDataEventArgs args)
	{
		AddressCorrected(null, args);
		Console.WriteLine("Adress is corrected");
	}

	public void CallProductStocked(ExternalDataEventArgs args)
	{
		ProductStocked(null, args);
		Console.WriteLine("Product is stocked");
	}
}

RC: Oh OK. So this class will be consumed by the client, right?

Shiv: Yes, that is absolutely right. We need to create the workflow instance using the workflow runtime and start the instance. We also need to add the order class clsorder object as a service.

C#
WorkflowInstance objWorkFlowInstance;
WorkflowRuntime objWorkFlowRuntime = new WorkflowRuntime();
clsOrder objOrder = new clsOrder();
ExternalDataExchangeService objService = new ExternalDataExchangeService();
Guid InstanceId = Guid.NewGuid();
objWorkFlowRuntime.AddService(objService);
objService.AddService(objOrder);
objWorkFlowInstance = objWorkFlowRuntime.CreateWorkflow(
   typeof(OrderWorkFlow.WorkflowOrder), null, InstanceId);
objWorkFlowInstance.Start();

RC: OK, so how will the complete client code look like?

Shiv: Shown below is the code snippet which shows how our client code looks like. What I have done is I take inputs and invoke the workflow methods accordingly.

C#
WorkflowInstance objWorkFlowInstance;
WorkflowRuntime objWorkFlowRuntime = new WorkflowRuntime();
clsOrder objOrder = new clsOrder();
ExternalDataExchangeService objService = new ExternalDataExchangeService();
Guid InstanceId = Guid.NewGuid();
objWorkFlowRuntime.AddService(objService);
objService.AddService(objOrder);
objWorkFlowInstance = objWorkFlowRuntime.CreateWorkflow(
   typeof(OrderWorkFlow.WorkflowOrder), null, InstanceId);
objWorkFlowInstance.Start();
Console.WriteLine("Work flow started"); 
ExternalDataEventArgs objDataEventArgs = new ExternalDataEventArgs(InstanceId);
objDataEventArgs.WaitForIdle = true;
Console.WriteLine("1 - This order is not paid");
Console.WriteLine("2 - Product is InStock");
Console.WriteLine("3 - Payment is made for this Order");
Console.WriteLine("4 - Dispatch the Order");
Console.WriteLine("5 - Adress is not Proper");
Console.WriteLine("6 - Adress is corrected");
Console.WriteLine("7 - Product is stocked");
Console.WriteLine("Enter Appropriate inputs ");
int intValueEntered=0;
while(intValueEntered < 7)
{
    intValueEntered = Convert.ToInt16(Console.ReadLine().ToString());
    if (intValueEntered == 1)
    {
        objOrder.CallNotPaid(objDataEventArgs);
    }
    else if (intValueEntered == 2)
    {
        objOrder.CallInStock(objDataEventArgs);
    }
    else if (intValueEntered == 3)
    {
        objOrder.CallPaymentMade(objDataEventArgs);
    }
    else if (intValueEntered == 4)
    {
        objOrder.CallDispatch(objDataEventArgs);
    }
    else if (intValueEntered == 5)
    {
        objOrder.CallAddressNotProper(objDataEventArgs);
    }
    else if (intValueEntered == 6)
    {
        objOrder.CallAddressCorrected(objDataEventArgs);
    }
    else if (intValueEntered == 7)
    {
        objOrder.CallProductStocked(objDataEventArgs);
    }
}

RC: OK, let me run it. Great, I can see the order is first placed, then when I enter 2, the product is moved in stock, and when I do dispatch, it moves in to a delivered state.

Image 16

Shiv: The most important part in the workflow is the workflow logic in your workflow project and your business component are self contained and they do their own activity.

RC: Great man, from where can I download the code? Tonight, I would like to see it when I reach home.

Source code

Shiv: You can find the source code for this article here. In case you are still not clear with workflow basics, you can read WWF.aspx.

For further reading do watch the below interview preparation videos and step by step video series.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect https://www.questpond.com
India India

Comments and Discussions

 
Generalsimple, lucid and evolutionary Pin
haridasa15-Apr-10 19:49
haridasa15-Apr-10 19:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.