Monday, October 24, 2011

Sum the first n numbers workflow with WF4

The idea of this simple workflow is to ask the user to introduce a number n and then the workflow will produce the sum of the first n numbers. So, using the workflow editor, we start by dragging a Sequence activity. Then, we insert a WriteLine activity that will ask to the user for a number
As we can see in the previous image, it was necessary to define a new argument of type int, i.e., we defined an InArgument for accepting input arguments when initialized in the WF host. By using InArgument, OutArgument, and InOutArgument, we can flow data into the workflow when it starts and out of the workflow when it ends. But for passing data from the caller into the workflow when it is executing we need to create a new activity. We will create and define this activity as ReadNumber activity. For creating this new ReadNumber activity, we have to create a new code file, for instance named as ReadNumber.cs, with the  following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;

namespace SumIntegers
{
    public sealed class ReadNumber : CodeActivity
    {
        public OutArgument<int> OutNumber { get; set; }
        protected override void Execute(CodeActivityContext context)
        {
            OutNumber.Set(context, Int32.Parse(Console.ReadLine()));
        }
    }
}

We must save and build the project so that we can use this activity in workflow designer. Therefore, in the workflow designer we can drag this new  activity to the sequence activity, as we can see in the following image

In the properties of the ReadLine activity, we associate the OutAurgument OutNumber to the InArgument n.
Then, we also drag inside to the Sequence activity the Assign activity, for assigning to a variable the value of the sum. For this, we have to define a new variable sum, as it is in the following image

The variable has a type, in this case Int32, and also a scope, which in this case is the sequence activity scope.
For doing the sum,  we may also define a new variable i and a While activity for incrementing the sum variable.
The following image shows all the workflow:


As we can see, we have defined inside the body of the While activity a new Sequence activity, that for each turn, includes two Assign activities for updating variables i and sum. The While activity has also a stopping condition that ensures that it is the sum of the first n numbers. The workflow ends printing to the Console the result of the sum.

Creating the workflow in WF using C# code

For creating a workflow using C# code and using Visual Studio 2010, we start by selecting  File -> New Project -> C# section -> Console Application to create a new project. It is necessary to add a reference to the System.Activities assembly, as already mentioned in "A first workflow with WF4".

Change the Program.cs file to:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Statements;
using System.Activities.Expressions;

namespace SumCodeNumbers
{  
 class Program
 {
  static void Main(string[] args)
  {    
   WorkflowInvoker.Invoke(new MyActivity());
  }

   public class MyActivity : Activity
   {
    public Variable<int> sum = new Variable<int>("sum", 0);
    public Variable<int> i = new Variable<int>("i", 0);
    public InArgument<int> n { get; set; }

    public MyActivity()
    {
     this.Implementation = () => new Sequence()
     {
      Variables = { sum, i },
      Activities ={
          new WriteLine(){
               Text=" Insert a number"
          },
          new ReadNumber(){
               OutNumber=new OutArgument<int>(env=> n.Get(env))
          },
          new While(){
            Body = new Sequence(){
               Activities ={ 
                 new Assign<int>{
                     To=new OutArgument<int>(sum),
                     Value = new InArgument<int>(env => 
                                         sum.Get(env)+i.Get(env))
                },
                new Assign<int>{
                    To=new OutArgument<int>(i),
                    Value = new InArgument<int>(env => i.Get(env)+1)
                }          
                }
                  },
                              
            Condition=ExpressionServices.Convert<bool>
                                (env=> i.Get(env)<=n.Get(env))
           },
          new WriteLine(){
              Text=new InArgument<string>(env=> "The sum is " +  
                            sum.Get(env).ToString())
          }
        },
       };
      }
     }
   }
}

In this example, we have also included in the project the file ReadNumber.cs.

Sunday, October 23, 2011

How to implement the workflow sequence pattern in WF4

The Sequence Pattern is used to construct a sequence of consecutive activities, which execution turn one after the other.


Creating a sequence workflow in WF
Using Visual Studio 2010, we start by selecting File-> New Project-> C# section->workflow->workflow console application to create a new workflow. We can name the project SequenceWorkflow.

First, drag a Sequence activity to the designer from the Toolbox. Next, drag two WriteLine activities into the Sequence activity. We can see the following screenshot

If we run the project, without debugging, the result will be:

Creating the first workflow in WF using C# code: Sequence Workflow

For creating a workflow using C# code and using Visual Studio 2010, we start by selecting  File -> New Project -> C# section -> Console Application to create a new project. It is necessary to add a reference to the System.Activities assembly, as already mentioned in "A first workflow with WF4".

Change the Program.cs file to:

    class Program
    {
        static void Main(string[] args)
        {
            WorkflowInvoker.Invoke(new SequenceWorkflow());
        }


        public class SequenceWorkflow : Activity
        {
            public SequenceWorkflow()
            {
                this.Implementation = () => new Sequence()
                {
                    Activities = {
                        new WriteLine() { Text = "Hello Workflow" },
                        new WriteLine() { Text = ""+ DateTime.Today.Day}
                    }
                };
            }
        }
    }
 

As we can see from this example, we set the implementation of this workflow with the delegate that returns an activity that contains the execution logic. In this case, the activities of the defined sequence are two WriteLine activies, that are executed in the defined order.
Notice also that by implementing a class inherited from Activity, we define a workflow using imperative code.

A first workflow with WF4

In software development, the main goal is to solve real business problems. A workflow is a sequence of ordered steps to realize in order to accomplish a goal, according to a set of rules.
Windows Workflow Foundation (WF) gives a framework for developing workflows in (.Net). In WF, a workflow can be defined  in three different ways: with C# code;  in XAML (eXtensible Application Markup Language, a declarative language used in Windows Framework); partially in C# code and in XAML.  To develop workflows in XAML we can use the WF editor or we can explicitly write the XML tags (XAML files are valid XML files)

Wokflows in WF 
The primary building block in Windows Workflow is the activity. All activities in WF derive from an Activity base class. Activities compose the steps, or tasks in a workflow, and define the workflow. We can arrange activities into a hierarchy and feed the activities to the workflow engine as instructions to execute.

Creating the first workflow in WF: Hello Workflow
This workflow is a simple one which only print  "Hello Workflow" to the console application.
Using Visual Studio 2010, we start by selecting  File -> New Project -> C# section -> Workflow-> Workflow Console Application to create a new WF project. We can name the project HelloWorkflow.

First, drag a WriteLine activity to the designer from the Toolbox. Then, input "Hello Workflow" in the expression box of the WriteLine activity. We can see in the following screenshot:

 When we run the project, the main method in the Program.cs file will execute
       WorkflowInvoker.Invoke(new Workflow1());
which starts the workflow. WorkflowInvoker provides a means for invoking a workflow. The WorkflowInvoker.Invoke method is synchronous and invokes the workflow on the same thread as the caller. After the workflow starts running, the WriteLine activity prints the "Hello Workflow" to the Console Application.

Creating the first workflow in WF using C# code: Hello WorkFlow

For creating a workflow using C# code and using Visual Studio 2010, we start by selecting  File -> New Project -> C# section -> Console Application to create a new project. It is necessary to add a reference to the System.Activities assembly for using, for instance, the WriteLine activity.

Open Program.cs file and add to the used namespaces, the System.Activities and System.Activities.Statements namespaces.  System.Activities namespace will we needed for instance, for using the WorkflowInvoker class and System.Activities.Statements namespace will be needed, for instance, for using the WriteLine class.
Change the Program.cs file to:

using System.Activities;
using System.Activities.Statements;

namespace HelloCodeWorkflow
{
    class Program
    {
        static void Main(string[] args)
        {
            Activity wf = new WriteLine() { Text = "Hello World." };
            WorkflowInvoker.Invoke(wf);
        }
    }
}

The WorkflowInvoker will invoke the defined activity wf and Text is a property of this activity.