Understanding Windows Workflow Foundation - Leave Management

Hey all. It's been a couple of years since I have contributed to a technical group since I have been busy growing up myself as a professional. Today I thought of contributing something that can be useful for beginners, trying to work with the Window Workflow Foundation.

Windows Workflow Foundation for .Net (in short “WWF”) was released by Microsoft in the year 2006-2007 timeframe (code named workflow) that basically provides Application Programming Interfaces (APIs) to a work flow engine.

I often hear from my teams and colleagues that everything is “automatic” in the field of software but personally I would say “Nothing is Automatic, we need to write a code snippet to make it automatic”.

The Windows Workflow Foundation is a very classic example of code that can be auto-generated though :) with the visual elements. For example if I were to do a parallel activity in my application, I would generally prefer to use Asynchronous Delegates. But with the use of the workflow foundation you can just drag and drop the parallel activity (available in the toolbox where you can create a workflow project) that can save a lot of code for the development team. Thanks to Microsoft for giving us such an interactive and high-performance framework and making our life easier than ever.

You can also download the source code from here

Before I jump into a code sample, let me talk about a couple of important components in the workflow process. Nevertheless to say, as for every project type in .Net framework,  the workflow foundation also has the capability to be developed as:

  • Activity Library that is a component with .DLL as output.

  • WCF Workflow Service Application that behaves like a WCF service.

  • Activity Designer Library that is a GUI based application with Windows Presentation Foundation (WPF).

  • Workflow Console Application that will be a console-based application.

Let me use a very simple use-case of leave management that everyone is completely aware of.

Two steps must be covered in the given use-case as: Leave Apply and Leave Approve. In the following given example, I have adopted an Activity Library to implement the workflow mechanism for Leave Apply.

To start a new activity library project, navigate to the File menu of the Visual Studio Integrated Development Environment (IDE) , select “New” and then “Project” (refer to the following screenshot).

Once you see the listing of templates, select “workflow” from Visual C# and then select “Sequential Workflow Library” (refer to the following screenshot). Please observe that the name of the project is SampleWorkflow-LM.

Don't worry, Sequential is really not sequential in workflow. We can make it s parallel activity that I will explain in the later steps.

There you go, you now are all set to design a new workflow. As I was selecting sequential workflow, you can see that the visual design screen prompts you to add a new workflow. Rename the workflow1.cs file to Requestworkflow.cs.

Now, as I said you earlier, sequential workflow is not really sequential and we can make it parallel. Select “Parallel” from the toolbox and drag and drop it to just below the sequential workflow activity on the designer. (Refer to screenshot below.)

Let's pause for a while here to understand what we actually did by doing a drag and drop of a parallel activity onto the designer. As you can see, a new parallel activity is created with again two branches of sequential activities and finally terminating the workflow activity.

The quick use-case I can think of here is to send email notifications to the leave application and to the leave approver in parallel. If you want to change the properties/name of the activities, do a right-click on the activity for a menu and then select “Properties” (refer to the screen shot below), that I am not doing in my sample.

Let's define the actual activity now. The next step is to get the workflow to understand the type of activity to be done. A workflow has many possible options, like event driven, code, if-else, while fault handling and so on. That you can see in your tool box. Let us pick “code” as our activity to send the e-mail notifications. Drag and drop the code activity from the toolbox onto the designer window just below the sequence activity1. Do the same for sequence activity 2. Rename the code activities to “Approver Notification” and “Applier Notification” by selecting the properties. Now, your screen should be such as in the following screenshot.

Always remember that when we are developing a component of (. DLL) output, there should either be a wrapper to invoke the component or there should be a direct invocation by reference adding the component in your project. As you are aware we need an object to hold the data for email notifications.

  1. public Hashtable requestorleavedata { getset; } .  

Public Hash tables

The Hash table is declared public to invoke the component by sending data. I prefer to use a Hash table to send the email notifications, but it can be a string/class/XML and so on (no restriction on serialization).

Two more methods are required now to complete the assignment.

  1. ///method to send email notification to the approver   
  2. private void NotifyApprover(object sender, EventArgs e)  
  3.         {  
  5.             try  
  6.             {  
  7. //logic to send the email using SMTP/Mail Server  
  8.             }  
  9.             catch (Exception ex)  
  10.             {  
  11.                 //log the error   
  13.             }  
  15.         }  
  18. ///method to send email notification to the applier   
  19. private void NotifyApplier(object sender, EventArgs e)  
  20.         {  
  22.             try  
  23.             {  
  24. //logic to send the email using SMTP/Mail Server  
  25.             }  
  26.             catch (Exception ex)  
  27.             {  
  28.                 //log the error   
  30.             }  
  32.         } 

Once you are done with the method implementation, navigate back to designer and right-click on the code properties (ApproverNotification) and select properties.navigate to the “ExecuteCode” property and choose the respective method name for both of the code activities. In our example, you need to choose the “notifyapprover” method for the “ApproverNotification” code activity and the “notifyapplier” method for the “ApplierNotification” code activity (refer to the screenshot below).

Please ensure that there are no compilation errors. If no errors, bingo! You have just developed a new workflow activity and you are done from the workflow perspective.

To invoke the same from your business logic, use the following code. When I say business logic, it might be your MVC application from where the leave applicant is applying for leave or it can be your WCF business logic component that saves the data in your database.

In my case, I have developed a WCF service with a business logic layer to save the leave data to my SQL database. Once the leave data is saved the following method can be used to invoke the workflow.

  1.          /// <summary>  
  2.         ///Author: Praveen Alwar  
  3.         /// Initiate the leave apply workflow process  
  4.         /// </summary>  
  5.         /// <param name="leavedata"></param>  
  6.         /// <param name="isapproved"></param>  
  8.         private void invokeworkflow(Hashtable hashdata,bool isnewleave)  
  9.         {  
  10. //A workflow is always run asychronously; the main thread waits on this event so the program does not exit before the workflow completes.  
  12.                 AutoResetEvent waitHandle = new AutoResetEvent(false);  
  14.                 using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())  
  15.                 {  
  17.                     Dictionary<stringobject> parameters = new Dictionary<stringobject>();  
  18.                     Type type = null;  
  20.                     if (isnewleave) //new leave request  
  21.                     {  
  22.                         parameters.Add("leavedata", hashdata);  
  24.                         // Get the workflow type  
  25.                          type = typeof(Requestworkflow);  
  26.                     }  
  28.                         // Create and start an instance of the workflow  
  29.                         workflowRuntime.CreateWorkflow(type, parameters).Start();  
  31. //waithandle will wait for the response for a definite time [milliseconds] or until the response if “-1” is set  
  33.                         waitHandle.WaitOne(-1,false);    
  35.                       workflowRuntime.StopRuntime();  
  38.             }  
  39.         } 

The preceding method invokes the “RequestWorkFlow” and you do need to ensure that the “SampleWorkflow-LM. DLL” is added as a reference DLL to your ceiling project. RequestWorkFlow accepts a hash table as an input parameter to execute the mail notification code. The following is just a sample of how to define a new hash table and fill in the required data in (key, value) format.

Note that the hash table data filling in should be from the calling method and not from the workflow.

  1. //fill the leave data hashtable with all required details  
  2. Hashtable _leavedata = new Hashtable();  
  3. _leavedata.Add(“@applicantemailid”,”xxxx@aa.com”); 

Just add the following line to call the “invokeworkflow()” method from the applyleave method (I am assuming that you will build a GUI/Service to store the data with the applyleave() method to input data from the leave applicant).

  1. invokeworkflow(_leavedata,true); 

Compile your calling application now and you are all set to experience the windows workflow activity.

I hope this explains in much detail how to start your initial code activity using workflow. I will contribute the approval workflow in my next article.

You can also download the source code from here.

Keep Smiling :)