Pages

Thursday, January 5, 2012

Workflow Foundation Project Using Visual Studio 2008 Express Edition


Introduction
This article can help any .NET developer, either C# or VB.NET, starting to program the Windows Workflow Foundation, using the freely available Microsoft Visual Studio 2008 Express Edition.
Background
A limitation in the Visual Studio 2008 Express Edition is the missing of the Standard and Professional Edition designers for many application and project types, including the new .NET 3.0 and 3.5 Framework Workflow Foundation.
Windows Workflow Foundation is a framework that enables users to create system or human workflows in their applications written for Windows Vista, Windows XP, and the Windows Server 2003 Operating Systems. It consists of a namespace, an in-process workflow engine, and designers for Visual Studio 2005 / 2008. As mentioned, these designers are missing in the Express Edition of Visual Studio.
Using the Code
The code for this article has been adapted from the Standard Microsoft training resources available here, which is a package of samples for Windows Communication Foundation (WCF), Windows Workflow Foundation (WF), and Windows CardSpaceA.
I have selected the simplest sample named SimpleSequentialWorkflow to adapt in this educational article to show a working WF example compiled and created inside Visual Studio 2008 Express Edition.
The attached download FirstWF.ZIP is a complete solution that has been created, compiled, and run inside VS 2008 Express Edition. You can just extract it and run it from a VS 2008 Express Edition Session.
Now, let's quickly get our hands dirty ..
  1. Open VS 2008, and from the File menu, choose New Project, and select Console Application, then give it a name. (On the right hand panel called Solution Explorer, select the solution node, and from the menu, choose File - Save Solution As, to better locate your solution and project files under a folder of your choice).
  2. A default skeleton class named Program.cs has already been created for you. Select References from the right hand Solution Explorer window and right click to add references to the following WF .NET class libraries System.Workflow.Runtime, System.ComponentModel, and System.Workflow.Activities.
  3. From the attached solution of this article, copy and paste the code for the Program.cs C# source file. (Ignore any compile errors that might appear at the moment).
  4. From the Solution Explorer window, select Project node and right click Add New Item of type C# Class. Give it the name SequentialWorkflow.
  5. From the attached solution of this article, copy and paste the code for the SequentialWorkflow.cs C# source file. (No compile errors should appear now!)
Now, let's have a brief look at the following code snippets (SequentialWorkflow.cs):

public sealed class SequentialWorkflow : SequentialWorkflowActivity
This is the class declaration for the type SequentialWorkflow to be instantiated at run-time by the WF Workflow Runtime, to host and then run the work flow activities of our example.
The activities are created and run inside the constructor of this class to have a simple all in one example. Usually, it should be implemented in another source file(s) in large projects. Our workflow in this sample is a simple approval process that checks an imaginary limit, and in this case, returns true every time, as in the code below.

private void IsUnderLimit(object sender, ConditionalEventArgs e)
{
    e.Result = true;
}
The constructor of the SequentialWorkflow class takes care of creating the activities required to implement the Workflow.
The following line initializes the private member IsUnderLimitIfElseActivity. Then, a System.Workflow.Activities.CodeCondition activity is created to evaluate the this.IsUnderLimit call (always true!). The ativity branches for the 111 are also created, and the YesIfElseBranch branch is assigned the codecondition1 to further process the evaluation of the approval. The code is illustrated below ..

 this.CanModifyActivities = true;
System.Workflow.Activities.CodeCondition codecondition1 =
    new System.Workflow.Activities.CodeCondition();
this.IsUnderLimitIfElseActivity = new System.Workflow.Activities.IfElseActivity();
this.YesIfElseBranch = new System.Workflow.Activities.IfElseBranchActivity();
this.NoIfElseBranch = new System.Workflow.Activities.IfElseBranchActivity();
this.ApprovePO = new System.Workflow.Activities.CodeActivity();
this.RejectPO = new System.Workflow.Activities.CodeActivity();

//
// IsUnderLimitIfElseActivity
//

this.IsUnderLimitIfElseActivity.Activities.Add(this.YesIfElseBranch);
this.IsUnderLimitIfElseActivity.Activities.Add(this.NoIfElseBranch);
this.IsUnderLimitIfElseActivity.Name = "IsUnderLimitIfElseActivity";

//
// YesIfElseBranch
//
this.YesIfElseBranch.Activities.Add(this.ApprovePO);
codecondition1.Condition += new
  System.EventHandler<System.Workflow.Activities.ConditionalEventArgs>(this.IsUnderLimit);
this.YesIfElseBranch.Condition = codecondition1;
this.YesIfElseBranch.Name = "YesIfElseBranch";
Now, all the magic is started from the Program.cs console application C# file, which creates a WorkflowRuntime as shown below, that hosts the work flow of type SequentialWorkflow. Next, this runtime object instance starts / initiates (at runtime, using Reflection) an object instance on another thread of the derived SequentialWorkflow class type, SequentialWorkflow. This kicks off the workflow process for our imaginary approval so that the IfElse is called, the CodeCondition is run to evaluate the CodeActivity for approval, then the IfElse branch activities are called depending on the results..

using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
    try
    {

        Console.WriteLine("Runtime Started.");
        // Load the workflow type
        Type type = typeof(SequentialWorkflow);
        // Listen for the workflow events
        workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
        workflowRuntime.WorkflowTerminated += OnWorkflowTerminated;
        // Create an instance of the workflow
        workflowRuntime.CreateWorkflow(type).Start();
        Console.WriteLine("Workflow Started.");
        ...
The rest of the glue and helper code is simple to read through. In a brief note, it just hooks an event handler to report the status of the workflow thread that has been started above when it has completed its work.
Points of Interest
This was a bare boned WF example created with no need for the VS WF designer using the Express Edition of Visual Studio, and illustrated a sequential work flow for an approval that used the standard WF CodeCondition Activity as well as the IfElseActivity, IfElseBranchActivity, and CodeActivity.
Hope this helps someone out there..!

No comments:

Post a Comment