It works on my machine

Learning WF - Part 5

In this installment we will look at creating custom activities for our workflows. Why do we need a custom activity? This answer is obvious, no matter how many activities are provided by default, there will be a need for the ability to write your own. Why do we need to write a custom activity when we have the code activity where you can write any arbitrary code. Well, it does not give us reusability and the additional benefits that we get with the custom activity.

All actvities are derived from either System.Workflow.ComponentModel.Activity or CompositeActivity. For the current excercise lets derive one from Activity class. First create a new sequential workflow. Then right click the project and add an activity.

By default this activity is derived from the Composite Activity class but for the moment we need a simple activity. So change its property Base Class to System.Workflow.ComponentModel.Activity. Our activity will have the special ability to calculate squares of any number. We need to add two properties to it.

These properties will appear in the Properties windows for this activity. Now the execution of an activity takes place in the Execute function. This function is already defined in the base class, here we need to override it.

The Execute function returns a enum of the type ActivityExecutionStatus to the runtime to indicate what state it is in. The possible states could be:

For the purpose of this tutorial we will just return the closed state to indicate that our work is done. Now lets use the activity we just created. For that do a build on the project and open the workflow. You will see the new activity in toolbox on top.

Drop this activity on your workflow and set its input value property to 2. Then drop a code activity next to it and add the following code:

 

Now run the activity. You can add any code you want here and reuse it.

With that out of the way, lets look at what else we can do with this activity. First we can try to customize its look and feel by decorating the class with some attributes. Lets assign it a nice icon for the designer.

I have used a bitmap file for the icon here. Build the solution so that the icon is recognised and open the designer window now.

You must have noticed the red error sign that appears with the activities if something needs to be specified. We can create such errors of our own by adding a similar attribute. Let's say I want to square values only between 1 and 100. I will need to addd the following class:

 The ActivityValidator class allows you to add the validation functionality. By default the actvities have this class attached to them but you can derive from this class and create your own validation errors. Then this class has to be attached to the particular activity you want to check.

Build and go to the designer, assign different values and see what it looks like.

This concludes the part on creating your own activities. In the next post we will look at host and workflow communication.

Posted: Apr 29 2008, 19:03 by raza | Comments (0) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: .Net | WF

Learning WF - Part 4

Continuing from our previous part we will use the same example to understand the exception handling and cancellation mechanism in WF programs.  Exception handling in concept is pretty much the same as in programming languages and emulates similar behavior for easy adaptation. Cancellation is, on the other hand, something we don't deal with regularly.

So let's look at the familiar exception handling first. In WF exception handling is implemented in similar fashion at the level of a block of activities such as sequence or parallel or the whole workflow itself. Let's take the previous example:

and place and exception in one of the activities. I'll add it to the codeActivity1.

Let's run it and by default it should be caught by the runtime, though our workflow would crash.

Now let's catch it within our workflow so that we can do something about it. For that you need to right click on the workflow level and select View Fault Handler, this would show something like the following:

Here we need to drop a fault handler from the toolbox. Then we can put whatever activities we need to handle this error, it could be a whole workflow in itself. But for the moment let's just go with a code activity.

For the first red bubble you need to specify the FaultType this handler is supposed to "catch" and for the second you just need a event handler. Let's assign the FaultType to System.Exception which we raised in our workflow.

In the handler put the following code:

Let's run it.

Now instead of the original error we see the message we printed, hence we can catch any errors and take whatever action we need to rectify it. But as I said, exceptions can be caught at any block level which means that we can localize the error handling to the block where it occurred. Let's do that:

Follow the same process as before and write a handler for it, run it and see that now you can catch it locally.

With exception handling taken care of we move to cancellation. Now cancellation is not your usual programming language feature. A cancellation occurs when you have multiple active branches in the same workflow (for example using parallel) and one of them throws up an error. The branch with error gets an exception but other branches get a cancellation. For us to test this functionality we need two simultaneously executing branches, so we'll use our parallel activity. Move the line that throws the exception from code activity one to two.  Put a cancellation handler on the other branch of the parallel activity. Also change the exception condition to avoid skipping it.

As opposed to exception handling, cancellation is a general event hence you just need to add whatever activities that you need to clean up after this cancellation.

Let's add the following code to the code activity:

and run it.

So the second branch was canceled, its cancellation handler called and then the exception was escalated to the level where it was caught by some handler.

Before we conclude this post let's look at another way to raise the exception that we did through code because many times it is done intentionally to signal known error conditions. For that you have the Throw activity. Drop a throw activity after code Activity 2 where we raised the last error and removed the line from code that raises the exception.

Now the code activity will perform its usual function while the error would be thrown by our new activity.  We now just need to specify what error to throw. Go to the properties of the Throw activity and set the following:

Now run the code to see cancellation and exception handling. If you would like to throw this error on the same condition as before you will have to drop another If-Else here. This concludes the fourth part of this series. In the next part we will look at writing custom activities. 

Posted: Apr 25 2008, 16:11 by raza | Comments (0) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: .Net | WF

Learning WF - Part 3

In this installment we will look at some simple activities and their use. In the previous posts I have used the code activity so I will not repeat that and move on to other activities. We begin by creating a sequential workflow console project. The designer should come up for us to place activities.

Sequence Activity

The sequence activity allows you to create a block of activities just like you create a block of code statements by putting { } around them. As the name suggests the sequence actvitiy runs all the statements embedded in it in sequence.  There are two types of activities in WF:  basic and composite. The basic activity is the unit of task we perform, it performs one particular action. The composite activity on the other hand allows you to combine basic activities creating activity blocks. Sequence is one such activity.

We create handlers for them by double clicking.

and then run it see results.

If-Else Activity

The second activity that you need from your structured programming toolbox is the condition or if-else activity. To use this activity drop it from the toolbox on to the designer and move code activity one to its left brach which is represents the if condition and code 2 to the right branch which is else. Delete the sequence and it should look like this.

The red warning means we need to specify something. When you click on it says that the condition property is not set, so let's do that. There are two types of conditions in WF: code and declarative. Code condition is a function which evaluates to true/false and you can do any kind of complex processing in it. Declarative is simpler and is useful for simple expressions, its use is also more common. Let's define a code condition first. For that you need to write a function that looks something like this:

 As you can see the evaluation is returned in the event parameter and you can do your complex evaluation before returning this result.  Now go to the designer and change the condition property to Code Condition and then expand to select the handler.

once this is done run the program and it should execute code activity 1 since the evaluation is true. Change the evaluation and run again to see the other branch execute.

While Activity 

The third structured programming activity is the loop, which is called While activity here. Drop a while activity from the toolbox to the designer window and move the if-else condition inside the loop, it should look like this.

The while also needs a condition, this time we will use the declarative condition. click on the red warning and select the condition. But first add a variable to the workflow class so that we can create condition on something.

Now go to condition and add the following:

We have put a condition on count but now we also need to add code to subtract the value for every iteration. For the moment lets add the statement "count--;" to both the handlers of code activity 1 and 2. Running the workflow now gives us:

Code activity 1 was executed ten times because the if condition is returning true every time. Lets change it to switch between the two code activities using the odd/even test. Change the condition for if-else to the following:

then run again.

Parallel and Delay Activity

Now let's use the parallel and delay. They are not linked in anyway but for the purpose of this post I am describing  together.  Drop a parallel activity from the toolbox to the designer in the else branch of the if-else. A parallel activity is the opposite of sequence and it executes activities in both branches independent of each other. Although the commonality between them is that both complete when all of their activities complete, so parallel would complete when all branches do. The designer should look like this:

 Lets configure the delay activity now. Its purpose is just to create a delay of whatever time you want to delay your workflow. In this case we are delaying the second branch of the parallel activity, which means that the whole of parallel activity would be delayed by this time, as it waits for all of its branches to complete, unless the other branch takes more time. Go to the properties of the delay activity and assign a two second delay to it.

Now run the workflow. Every second iteration should take more time now.

This completes the third part of the series. In the next part we will look at the fault and cancellation handlers.

Posted: Apr 25 2008, 16:10 by raza | Comments (0) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: .Net | WF

Learning WF - Part 2

In the first part we looked at what WF was and what would the simplest workflow would look like in code. Let's move on and use the tools that WF is meant to be used with. First of all, WF follows the same principles you find in other technologies that come with .Net 3.0, especially the Markup + Code = Application thing. You can completely code the workflow or you could break it up into code and markup. The markup being XAML.

I will create a simple workflow called, you guessed correctly, SimpleWorkflow. Also I am using VS 2008, so some screenshots may look slightly different than VS 2005.ScreenHunter_05 Apr. 19 22.20

If you right click the project and add new item, select workflow you see a number of options. Among them you have sequential and state workflow with code and sequential and state workflow with code separation. We select the sequential workflow with code separation meaning we generate a XAML file and a code behind file.ScreenHunter_06 Apr. 19 22.25

Workflow designer pops up. Let's drop a code activity in the designer and add some code to it, by double clicking the activity.

ScreenHunter_07 Apr. 19 22.34

ScreenHunter_08 Apr. 19 22.34

Now the workflow is ready, but we chose the empty project for workflow so we don't have a code that host's this workflow. Let's add a class with the main function and add the hosting code too.

ScreenHunter_10 Apr. 19 22.36

Running this code should give us the obvious result.

ScreenHunter_11 Apr. 19 22.38

Now coming back to the code/XAML separation thing. This time we created one such workflow so let's look into that separation.

ScreenHunter_12 Apr. 19 22.40

As you can see the XAML file has the extension xoml here (interesting!) and code has the usual one. If you double click the xoml file then it would open the designer, so you need to do a right click and open with the XML editor. Then you see this (slightly reformatted to fit the screen).

ScreenHunter_13 Apr. 19 22.41

It should be quite obvious how the markup is composed and how it links with the code. If you have worked with ASP.Net then it pretty much the same deal. This concludes the second part. In the next part we will look at using some simple activities.

Posted: Apr 24 2008, 20:15 by raza | Comments (0) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: .Net | WF

Learning WF - Part 1

Workflow Foundation part of the Microsoft .Net 3.0 framework is a wonderful new framework that allows you to design and create asynchronous processes using visual studio. Before we start with the framework itself we need to understand why do we have this framework in the first place? The answer is simple, it serves a common need. In business application it is common to capture the business processes and allow the user to run through it using a set of screens. A common example could be a user trying to get a day's leave or vacations.

The process would start out with the user going to a screen and launching the request, this would then be seen by HR who would redirect it to the manager of that user, it is then approved or disapproved and the result returned to HR then to the user.  Building such processes was a common pattern in business applications, so there was a need for a framework to generalize this task and allow for easy creation of such processes. WF as a framework differs from the packaged BPM solutions like K2.Net, which offer a complete set of tools for doing just this one task and is typically directed towards implementers. WF on the other hand is for developer to create custom implementations for whatever need there may be.

To start development with WF you need to have WF Extensions for VS 2005 and .Net Framework 3.0, if you are using Visual Studio 2005. If you have Visual Studio 2008 then you are already setup for development. Workflow Foundation is not that simple a framework to understand and required certain level or proficiency and maturity in both .net and development in general.

Let's start by writing some workflow code from scratch. If you start by creating a console application in C#, you need to add the following three references:

- Microsoft.Workflow.Activities

- Microsoft.Workflow.ComponentModel

-Microsoft.Workflow. Runtime

Start by adding the following:

using System.Workflow.Activities;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;

Define a class something like this:

class MinimalWorkflow : SequentialWorkflowActivity
    {
        public MinimalWorkflow()
        {
            CodeActivity ca = new CodeActivity();
            ca.ExecuteCode += delegate
            {
                Console.WriteLine("Hello World");
            };
            this.CanModifyActivities = true; //this is not required in VS2005
            this.Activities.Add(ca);
            this.CanModifyActivities = false; //this is not required in VS2005
        }
    }

The class above derives from the SequentialWorkflowActivity because everything in WF is considered an activity. Activity is the basic unit of workflow and the whole workflow itself is also an activity. There are two types of these activities, basic and composite. So you can guess that a basic activity would perform a task while composite would be anything that is made of other activities. Workflow itself is a composite activity and in this case it is sequential (step by step) in nature. CodeActivity is one of the basic activities that we can add to the workflow. All actions in the activities are event driven hence we put a delegate on the execute event for this activity.

The program that hosts or loads a workflow in memory is called the 'host' application. In our example we might write one like follows:

class Program     {       
        public static void Main(string[] args)
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime())
            {
                WorkflowInstance instance = runtime.CreateWorkflow(typeof(MinimalWorkflow));
                instance.Start();
                Console.ReadLine();
            }
        }
    }

At the minimum one needs to create the workflow runtime and using it instantiate the workflow. I am using an overload of the CreateWorkflow function that requires only a type, there are other that allow you to pass parameters and setup other details as well. After creating the workflow we need to start it. Since this is an asynchronous application the main function might exit without giving the workflow a chance to complete, hence the Readline. It ensures that the workflow will get enough time to load and trigger all its events.

This concludes part one. In succeeding posts I will cover different aspects of WF and explain relevant details with that aspect.

Posted: Apr 23 2008, 20:13 by raza | Comments (0) RSS comment feed |
  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Filed under: .Net | WF