This article provides overview of Windows Workflow Foundation and step by step to create simple Sequential Workflow which accepts Candidate Name and Years of Experience as parameter and returns ValidCandidate if years of experience is less than 7 otherwise InValidCandidate.
Introduction
This article provides overview of Windows Workflow Foundation and describes how to create simple Sequential Workflow.
Workflow Foundation Overview
Windows Workflow Foundation (WF) is a Microsoft Technology introduced in 2006 part of .NET Framework 3.0. It is a Framework for rapid development of workflow enabled applications.
What is Workflow?
“Workflow is the operational aspect of a work procedure: how tasks are structured, who performs them, what their relative order is, how they are synchronized, how information flows to support the tasks and how tasks are tracked.”
Workflow is a series of steps/activities that makes up the business process.
It can involve people or co-ordinate software
It can be long or short lived
It organize them into flow chart or state diagram
Components of Workflow
Workflow Runtime Engine: Every running workflow instance is created and maintained by an in-process runtime engine that is commonly referred to as the workflow runtime engine.
Host Process: When a workflow model is compiled, it can be executed inside any Windows process including console applications, forms-based applications, Windows Services, ASP.NET Web sites, and Web services
Runtime Services: Each service provides a feature that interacts with system outside the workflow. Runtime Services provide features that interact with the Runtime Engine i.e. Persistence, Tracking, Scheduling
Base Activity Library: Out-of-Box activities and base for custom activities library
Custom Activity Library: Custom Activities derive from Base Activity Library.
Workflow: Workflow is a set of steps / activities
Types of Workflow
There are two types of workflow
Sequential Workflow: A Sequential workflow runs from beginning to end, with the workflow engine initiating each step.
State Machine Workflow: A State Machine workflow is driven by external events and user interaction, and simply constrains or interacts with those events, so it stores state between events. State Machine workflows are called this because they allow the developer to define custom "states" that the process can be in at any time.
Creating Simple Sequential Workflow
We are going to create simple Sequential Workflow application which accepts Candidate Name and Years of Experience as input parameters and validate whether years of experience is less than 7, then return the status as “Valid Candidate” otherwise as “Invalid Candidate”.
1. In Visual Studio, from File Menu select “New” and then “Project”
2. When the New Project dialog box appears, expand the Visual C# tree control node and then select “Workflow” from the Project Types pane.
3. Select “Sequential Workflow Console Application” from Templates Menu
4. In the Name field type “SelectCandidateWorkflow”.
5. In the Location field type the location, say for example “C:\Arul\SeqWorkFlow”.
6. Click “Ok”
7. After creating the application, your designer window should look like this initially.
8. Open the Solution Explorer and expand the References,
System.Workflow.Runtime - Contains classes and interfaces that you can use to control the workflow runtime engine and the execution of a workflow instance.
The System.Workflow.Runtime namespace contains the “WorkflowRuntime” class, which you can use to configure, control, and subscribe to events for the workflow runtime engine associated with your application domain. The “WorkflowInstance” class provides a proxy to each workflow instance and lets you control the execution of a workflow. In addition to these classes, several classes having to do with workflow event queues and with exceptions thrown by the workflow runtime engine are contained in this namespace.
Since we selected the “Sequential Workflow Console Application” the references and using statements are already included otherwise we need add references to System.Workflow.Runtime manually.
9. Open the Workflow1.cs and define the following,
Variables and properties are defined to accept the parameters and return the status of the candidate whether he’s a valid or invalid candidate
private string candidateName;
private int yearsOfExperience;
private StatusType statusValue;
public enum StatusType
{
None,
ValidCandidate,
InValidCandidate
}
/// <summary>
/// Candidate Name property
/// </summary>
public String CandidateName
{
get
{
return this.candidateName;
}
set
{
this.candidateName = value;
}
}
/// <summary>
/// Candidate Experience property
/// </summary>
public int CandidateExperience
{
get
{
return this.yearsOfExperience;
}
set
{
this.yearsOfExperience = value;
}
}
/// <summary>
/// Status to return whether valid or invalid candidate
/// </summary>
public StatusType Status
{
get
{
return this.statusValue;
}
set
{
this.statusValue = value;
}
}
10. Open the Workflow1 in design mode then “Drag and drop the IfElse & Code Activity”
Name the first code activity as “actAccept” & define ExecuteCode as “AcceptDetails”
Add the following code
i.e. when condition is true, “AcceptDetails” is fired and we are setting the status as Valid Candidate.
/// <summary>
/// Set Status as Valid Candidate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void AcceptDetails(object sender, EventArgs e)
{
Status = StatusType.ValidCandidate;
}
Name the second code activity as “actReject” & define ExecuteCode as “RejectDetails”
Add the following code,
i.e. when condition is false, “RejectDetails” is fired and we are setting the status as Valid Candidate.
/// <summary>
/// Set Status as Invalid Candidate
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RejectDetails(object sender, EventArgs e)
{
Status = StatusType.InValidCandidate;
}
11. To validate candidate set IfElseBranchActivity1 Condition to Code Condition and
condition as “IsValidCandidate”. Add the following Code
/// <summary>
/// Validate Candidate and set the result to true if Candidate ///Experience is less
/// than 7 otherwise false.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void IsValidCandidate(object sender,
ConditionalEventArgs e)
{
e.Result = (CandidateExperience < 7);
}
Now the workflow is completed which accepts Candidate Name and Years of Experience and returns as Valid Candidate if years of experience is less than 7 otherwise as Invalid Candidate.
Hosting Simple Sequential Workflow with Console based application & Passing Parameters
Now we are going to Host the Workflow defined above and execute it.
1. Open the “Program.cs”
To pass parameters we use Dictionary object and add the following code
Dictionary<string, object> parameters = new Dictionary<string, object>();
Following is the code to accept CandidateName input and repeat the same to Candidate Years of Experience input
Console.Write("Enter Candidate Name : ");
parameters["CandidateName"] = Convert.ToString(Console.ReadLine());
if (parameters["CandidateName"].ToString().Length <= 0)
{
parameters.Remove("CandidateName");
}
2. Create instance of the WorkflowRuntime,
WorkflowRuntime workflowRuntime = new WorkflowRuntime();
3. Define the AutoResetEvent as follows
A workflow is always run asynchronously; the main thread waits on this event so the program does not exit before the workflow completes. AutoResetEvent is to block and release the thread by use of Set method. To do that we need to define the following
AutoResetEvent waitHandle = new AutoResetEvent(false);
4. Listen for Workflow Events
WorkflowCompleted event is raised when workflow instance is completed.
If we worked with Delegate, following code looks similar. When Workflow is completed, get the status and display the message whether Candidate is valid or invalid.
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
{
//Candidate Selection Status
string status = e.OutputParameters["Status"].ToString();
string candidateName = e.OutputParameters["CandidateName"].ToString();
Console.WriteLine(candidateName + " is " + status + " for the job. ");
waitHandle.Set(); //This signals to release the thread
};
WorkflowTerminated event is raised when workflow instance is terminated.
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};
5. Create and Start instance of the workflow.
So far we have created the Workflow, created instance of the WorkflowRuntime, accepted the parameters and defined the events WorkflowCompleted, WorkflowTerminated.
Now we need to create WorkflowInstance by passing parameters and start it.
WorkflowInstance instance = workflowRuntime.CreateWorkflow(
typeof(SelectCandidateWorkFlow.Workflow1),parameters);
instance.Start();
waitHandle.WaitOne(); //Wait for the signal to release the thread
6. So once Workflow is completed we need call StopRuntime.
workflowRuntime.StopRuntime();
7. Now everything, compile and execute the code. Sample Output.
Conclusions
This is how we create the simple Sequential Workflow and hosted with Console Application. There are other ways to create and host Workflow with ASP.NET, Windows Forms, Windows Services etc.
I will try to include those in my next article.
References
http://msdn.microsoft.com/en-us/library/ms735784(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms741685(v=VS.90).aspx
http://www.codeproject.com/KB/WF/SequentialWorkflowExample.aspx
http://en.wikipedia.org/wiki/Windows_Workflow_Foundation
http://www.ssw.com.au/ssw/Events/usergroup/Dec07/MarkLiu/Windows%20Workflow%20Foundation%20(WF).ppt.
MSDN
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/wf_gettingstarted/html/55da2060-f10f-4ef4-a923-b38e4504516b.htm
Books
Microsoft Windows Workflow Foundation Step by Step by Kenn Scribner