Showing posts with label Workflow (WF). Show all posts
Showing posts with label Workflow (WF). Show all posts

Thursday, October 02, 2008

* What’s new in .NET 4.0 ?

Now that features of .NET 4.0 have started becoming officially public… I am also happy to start blogging about them.

Based on the available info.. here is the link containing the new features coming out in .NET framework 4.0.

What’s new in .net framework 4.0

I will be updating this link on regular basis .. so bookmark it.

Tuesday, February 27, 2007

* Tutorial : Developing a state machine workflow

In this post i will demonstrate how to build a basic state machine workflow.

A state machine workflow consists of set of states with one state marked as 'start' state and one as 'final' state. Every state has an event associated with it and based on those events, workflow transitions from one state to another. It always starts from 'start' state and once it reaches the 'final' state, the workflow is assumed to be complete.

Few points about composition of a state machine workflow :

  • Every workflow consists of set of 'StateActivity'.
  • Each state is made up of one or more 'EventDrivenActivity', can contain one 'StateInitializationActivity' and can contain one 'StateFinalizationActivity'.
  • Each workflow has two properties 'InitialStateName' and 'CompletedStateName' to set the start and final state.
  • Wokflow can be transitioned from one state to another using 'SetStateActivity'.

Following are the steps to create a state machine workflow using Visual Studio 2005 and WF extensions for Visual Studio.

  • Start by creating an empty workflow project. Change the 'Output Type' to console application.
  • Add a new Item to the project : 'State machine workflow - with code separation' - Workflow1.xoml
  • Automatically a state will be added to workflow - Workflow1InitialState and the InitialStateName of the workflow has been set to Workflow1InitialState .
  • Drag and Drop two more states to the workflow. Name one as 'middleState' and the other as 'finalState'
  • Set the 'CompletedStateName property of workflow to 'finalState'
  • Drop an EventDrivenActivity to start state and within that drop a delayActivity, codeActivity and SetState Activity.
  • Set the delay for delayActivity say 5 sec.
  • Add code to code activity as follows :
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("In code activity of start state");
}








  • Set the TargetStateName property of SetStateActivity to 'middleState'.

  • In middle state activity, add an EventDriven activity and into it add a delayActivity, code activity and set state activity.

  • Set the TargetStateName property of SetStateActivity to 'finalState'.

  • Add code to code activity as follows :
private void codeActivity2_ExecuteCode(object sender, EventArgs e)
{
Console.WriteLine("In code activity of middle state");
}








  • Add a code file to the project for creating entry point for the program and hosting/executing the workflow.
using System;
using System.Threading;
using System.Workflow.Runtime;

namespace SimpleStateMachine
{
static class MainProgram
{
static AutoResetEvent waitHandle = new AutoResetEvent(false);

static void Main()
{
using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
try
{
workflowRuntime.StartRuntime();
workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
workflowRuntime.WorkflowTerminated += OnWorkflowTerminated;

Type type = typeof(Workflow1);
workflowRuntime.CreateWorkflow(type).Start();

Console.WriteLine("Running the workflow. Waiting for the timer events...");

waitHandle.WaitOne();
}
catch (Exception e)
{
Console.WriteLine("Encountered an exception. Exception Source: {0}, Exception Message: {1} ", e.Source, e.Message);
}
finally
{
if (workflowRuntime != null)
workflowRuntime.StopRuntime();
Console.WriteLine("WorkFlow Completed");
}
}
}

static void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs instance)
{
waitHandle.Set();
}

static void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
}
}
}








  • The layout file for the workflow will look somewhat like following :
<StateMachineWorkflowDesigner xmlns:ns0="clr-namespace:System.Drawing;Assembly=System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Name="Workflow1" Location="30, 30" Size="668, 554" AutoSize="False" AutoSizeMargin="16, 24" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<StateMachineWorkflowDesigner.DesignerConnectors>
<StateDesignerConnector TargetConnectionIndex="0" TargetStateName="middleState" SourceConnectionIndex="0" TargetConnectionEdge="Top" SetStateName="setStateActivity1" SourceStateName="Workflow1InitialState" SourceConnectionEdge="Right" TargetActivity="middleState" SourceActivity="Workflow1InitialState" EventHandlerName="eventDrivenActivity1">
<StateDesignerConnector.Segments>
<ns0:Point X="193" Y="110" />
<ns0:Point X="294" Y="110" />
<ns0:Point X="294" Y="341" />
</StateDesignerConnector.Segments>
</StateDesignerConnector>
<StateDesignerConnector TargetConnectionIndex="0" TargetStateName="finalState" SourceConnectionIndex="0" TargetConnectionEdge="Top" SetStateName="setStateActivity2" SourceStateName="middleState" SourceConnectionEdge="Right" TargetActivity="finalState" SourceActivity="middleState" EventHandlerName="eventDrivenActivity2">
<StateDesignerConnector.Segments>
<ns0:Point X="361" Y="382" />
<ns0:Point X="500" Y="382" />
<ns0:Point X="500" Y="190" />
<ns0:Point X="412" Y="190" />
<ns0:Point X="412" Y="198" />
</StateDesignerConnector.Segments>
</StateDesignerConnector>
</StateMachineWorkflowDesigner.DesignerConnectors>
<StateMachineWorkflowDesigner.Designers>
<StateDesigner Name="Workflow1InitialState" Location="46, 69" Size="160, 80" AutoSizeMargin="16, 24">
<StateDesigner.Designers>
<EventDrivenDesigner Size="110, 292" Name="eventDrivenActivity1" Location="54, 100">
<EventDrivenDesigner.Designers>
<DelayDesigner Size="90, 40" Name="delayActivity1" Location="64, 172" />
<CodeDesigner Size="90, 40" Name="codeActivity1" Location="64, 242" />
<SetStateDesigner Size="90, 50" Name="setStateActivity1" Location="64, 312" />
</EventDrivenDesigner.Designers>
</EventDrivenDesigner>
</StateDesigner.Designers>
</StateDesigner>
<StateDesigner Name="middleState" Location="214, 341" Size="160, 80" AutoSize="False" AutoSizeMargin="16, 24">
<StateDesigner.Designers>
<EventDrivenDesigner Size="110, 292" Name="eventDrivenActivity2" Location="309, 148">
<EventDrivenDesigner.Designers>
<DelayDesigner Size="90, 40" Name="delayActivity2" Location="319, 220" />
<CodeDesigner Size="90, 40" Name="codeActivity2" Location="319, 290" />
<SetStateDesigner Size="90, 50" Name="setStateActivity2" Location="319, 360" />
</EventDrivenDesigner.Designers>
</EventDrivenDesigner>
</StateDesigner.Designers>
</StateDesigner>
<StateDesigner Name="finalState" Location="332, 198" Size="160, 80" AutoSizeMargin="16, 24" />
</StateMachineWorkflowDesigner.Designers>
</StateMachineWorkflowDesigner>








  • Execute the workflow .. the successful output will be :


Running the workflow. Waiting for the timer events...
In code activity of start state
In code activity of middle state
WorkFlow Completed



~tata & take care~



Other Posts



Wednesday, February 21, 2007

* Workflow : Windows Workflow Services Overview

Windows Workflow foundation provides lot of services which can be plugged into workflow runtime based on the requirement. This reduces the overhead on runtime by having lot of services loaded without being used. These services come by default implementations but are fully extensible.

The main services which come with framework are :

  • Scheduling Services : This is to manage how workflows are scheduled. By default workflows are executed in async manner but they can be executed in manual synchronous manner also.
  • CommitWorkBatch Services : This is used to customize the commit process.
  • Persistence Services : Persistence service is used to make workflow failure proof and also to optimize the long running workflows. There are lot of events on which workflow runtime can call the persistence service if it has been added.
  • Tracking Services : Tracking service is used to monitor and troubleshoot workflows. There are lot of events which are raised by workflow runtime for various activity and workflow instance states. Tracking framework can be used to capture all these events and also user defined events. A default implementation using SQL Server as data store comes with framework.

Apart from extending above services, custom services can also be created and added to runtime.

Services are added to runtime using AddService method of the WorkflowRuntime class.

~bye & take care~

Other Posts

* WF Tutorial : How to create rule based condition for sequential workflow

This tutorial covers following :

  • Creating a Sequential workflow using code-separation authoring mode
  • Use Visual Studio 2005 and Windows Workflow Foundation extensions for VS
  • Demonstrates IfElse activity and rule based condition authoring

To start follow the first three steps as in following post.

  • In the next step drag and drop the IfElse activity on to the empty workflow file. The ifElseActivity with two ifElseBranchActivity will be added to your workflow
  • Also add the code activities for each of the IfElseBranch activities which will get executed whenever that branch evaluated to true. This can be done by dropping the Code Activity on each of the branch and setting the value of ExecuteCode parameter in the properties window. e.g. codeCondition1 and codeCondition2. Both the methods will be generated in code file. Modify the code as below :
 private void codeCondition1(object sender, EventArgs e)
{
Console.WriteLine("i equals zero is true");
}

private void codeCondition2(object sender, EventArgs e)
{
Console.WriteLine("i equals one is true");
}








  • Next add an instance member to your workflow class e.g. int i. The workflow class now will look like below :
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace RuleCondition
{
public partial class Workflow1 : SequentialWorkflowActivity
{
int i=1;

private void codeCondition1(object sender, EventArgs e)
{
Console.WriteLine("i equals zero is true");
}

private void codeCondition2(object sender, EventArgs e)
{
Console.WriteLine("i equals one is true");
}
}
}








  • Switch to design mode of workflow.In the properties windows of first ifElseBranch activity set the following parameters as below :



    • Condition -> Declarative Rule Condition

    • ConditionName -> iEqualsZero

    • Expression( which contains the actual condition to be evaluated) -> this.i==0 ; which means if i equals zero execute this branch.

    • As soon as these parameters are set a new file will be generated and added to project called Workflow1.rules where the above set condition is actually defined.


  • Similarly set the parameters to second Branch also as below:



    • Condition -> Declarative Rule Condition

    • ConditionName -> iEqualsOne

    • Expression -> this.i==1


  • Add a new code file to the project which will the entry point for this console application and will also host the created workflow :
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;

namespace RuleCondition
{
class Program
{
static AutoResetEvent waitHandle = new AutoResetEvent(false);
static void Main(string[] args)
{
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{

workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {OnCompleted();};
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};

WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(RuleCondition.Workflow1));
instance.Start();

waitHandle.WaitOne();
}
}
static private void OnCompleted()
{
waitHandle.Set();
Console.WriteLine("wf completed");
Console.Read();
}
}
}








  • Build and execute the project. As we have set the value of i=1 , the following output will be displayed :




i equals one is true
wf completed





  • Open the Workflow1.rules file. Well don't get scared, although its big for creating such a simple condition but its quite simple to understand. The main elements you need to look for are : RuleExpressionCondition, CodeBinaryOperatorExpression, CodeFieldReferenceExpression, CodePrimitiveExpression.Value. The file will have following code :
<RuleDefinitions xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<RuleDefinitions.Conditions>
<RuleExpressionCondition Name="iEqualsZero">
<RuleExpressionCondition.Expression>
<ns0:CodeBinaryOperatorExpression Operator="ValueEquality" xmlns:ns0="clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<ns0:CodeBinaryOperatorExpression.Left>
<ns0:CodeFieldReferenceExpression FieldName="i">
<ns0:CodeFieldReferenceExpression.TargetObject>
<ns0:CodeThisReferenceExpression />
</ns0:CodeFieldReferenceExpression.TargetObject>
</ns0:CodeFieldReferenceExpression>
</ns0:CodeBinaryOperatorExpression.Left>
<ns0:CodeBinaryOperatorExpression.Right>
<ns0:CodePrimitiveExpression>
<ns0:CodePrimitiveExpression.Value>
<ns1:Int32 xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">0</ns1:Int32>
</ns0:CodePrimitiveExpression.Value>
</ns0:CodePrimitiveExpression>
</ns0:CodeBinaryOperatorExpression.Right>
</ns0:CodeBinaryOperatorExpression>
</RuleExpressionCondition.Expression>
</RuleExpressionCondition>
<RuleExpressionCondition Name="iEqualsOne">
<RuleExpressionCondition.Expression>
<ns0:CodeBinaryOperatorExpression Operator="ValueEquality" xmlns:ns0="clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<ns0:CodeBinaryOperatorExpression.Left>
<ns0:CodeFieldReferenceExpression FieldName="i">
<ns0:CodeFieldReferenceExpression.TargetObject>
<ns0:CodeThisReferenceExpression />
</ns0:CodeFieldReferenceExpression.TargetObject>
</ns0:CodeFieldReferenceExpression>
</ns0:CodeBinaryOperatorExpression.Left>
<ns0:CodeBinaryOperatorExpression.Right>
<ns0:CodePrimitiveExpression>
<ns0:CodePrimitiveExpression.Value>
<ns1:Int32 xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">1</ns1:Int32>
</ns0:CodePrimitiveExpression.Value>
</ns0:CodePrimitiveExpression>
</ns0:CodeBinaryOperatorExpression.Right>
</ns0:CodeBinaryOperatorExpression>
</RuleExpressionCondition.Expression>
</RuleExpressionCondition>
</RuleDefinitions.Conditions>
</RuleDefinitions>






~bye & take care~



Other Posts



Tuesday, February 20, 2007

* WorkFlow (WF) : Developing Code Condition workflow using IfElse activity

If you are new to WF pls read my previous posts on WF before proceeding with this.

In this post i will cover following :

  • How to use IfElse Activity in sequential workflow provided by WF framework
  • Authoring conditions using code instead of declarative rules.

To start follow the first three steps as in following post.

In the next step drag and drop the IfElse activity on to the empty workflow file. The ifElseActivity with two ifElseBranchActivity will be added to your workflow.

  • Next step is to define the methods which will contain the condition logic for both of the ifElseBranch Activities.
  • In the properties window of the first ifElseBranch Activity set the value of Condition parameter as 'Code Condition' and method name as 'Condition1'.
  • For second ifElseBranch Activity set the values as 'Code Condition' and 'Condition2'
  • For both of the conditions. methods will be generated as below
private void Condition1(object sender, ConditionalEventArgs e)
{

}
private void Condition2(object sender, ConditionalEventArgs e)
{

}








  • Next add CodeActivity to both of the ifElseBranch Activities. The Code Activity will get executed whenever the corresponding ifElseBranch activity will get evaluated to true.

  • Add code method names conditionCode1 and conditionCode2 for the above Code Activities.

  • Both the condition code methods will get instance of ConditionalEventArgs as parameters. When the Result property of this instance is set as true, the condition is assumed to be satisfied.

  • Modify the code in Workflow1.xoml.cs as below :
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace SequentialWF
{
public partial class Workflow1 : SequentialWorkflowActivity
{
private void Condition1(object sender, ConditionalEventArgs e)
{
Console.WriteLine("condition one evaluated");
e.Result=true;
}

private void Condition2(object sender, ConditionalEventArgs e)
{
Console.WriteLine("condition two evaluated");
e.Result=false;
}

private void conditionCode1(object sender, EventArgs e)
{
Console.WriteLine("condition one executed");
}

private void conditionCode2(object sender, EventArgs e)
{
Console.WriteLine("condition two executed");
}
}
}








  • When the above workflow is executed the output shown is :




condition one evaluated
condition one executed -





  • Similarly if second condition is set to true and first as false the output shown is :

    condition one evaluated
    condition two evaluated
    condition two executed


  • Any number of ifElseBranch activities can be added to the workflow.


~bye & take care~



Other Posts



* WorkFlow (WF) : Defining Conditions based WorkFlow

Most of the workflow we see in our daily lives are multi path which means based on different condition they take different path before getting completed.

Be it a financial workflow like Funds Transfer happening in Corporate environment which based on amount goes to different approvers or a non-financial workflow like leave approval in an enterprise which goes to different approver based on who initiates the leave request.

WF default activity library provides IfElseActivity + IfElseBranchActivity activity to simulate condition based workflow.

WF provides two methods of defining condition in workflow :

  • Defining condition in code using the if-else statements of the language like :
if (i == 0)
{
Result = true;
}
else
{
Result = false;
}








  • Defining conditions using Rules which can be written programmatically or in XML file. The advantage which Rules provide over Code Conditions is that they can be changed at Runtime using Workflow changes.


~bye & take care~



Other Posts



Thursday, February 15, 2007

* WorkFlow (WF) : Developing a simple sequential workflow

This post gives step by step details on how to build a simple sequential workflow using Code Activity.

It assumes that all the components required to develop workflow apps have been installed. List can be obtained here.

Step 1 : Create an empty workflow project in VS 2005. Empty project helps in understanding the architecture of app better as we build from scratch.

Step 2 : As we will be building a console application, change the output type of the project to 'Console Application' using project properties.

Step 3 : Add a new item to the project- 'Sequential Workflow (with code separation)' where we will specify the workflow implementation. This will add two files to your project Workflow1.xoml and Workflow1.xoml.cs.

Step 4 : Double clicking Workflow1.xoml will open the empty workflow diagram. Drag and drop code activity from workflow toolbox on the workflow.In the property window of the code activity enter the value for ExecuteCode parameter which will generate the method by that name. e.g. Code1.

Step 5 : Add code to the Code1 method. Workflow1.xoml.cs will look like this :

namespace HelloWorld
{
public partial class Workflow1 : SequentialWorkflowActivity
{
private void Code1(object sender, EventArgs e)
{
Console.WriteLine("Hello workflow enabled world !");
}
}
}






Step 6 : Add a new code file to your project with Main method. This file will be used to host the workflow and execute it.



The code in the file should be :

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};

WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(HelloWorld.Workflow1));
instance.Start();

waitHandle.WaitOne();
Console.ReadLine();
}
}
}
}






Step 7 : Build the solution, the output should like like this :



Hello workflow enabled world !



The code in the markup file will be like this :

<SequentialWorkflowActivity x:Class="HelloWorld.Workflow1" x:Name="Workflow1" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<CodeActivity x:Name="codeActivity1" ExecuteCode="Code1" />
</SequentialWorkflowActivity>






Let me just explain some code now :



Class WorkFlow1 is quite simple and as we developed Sequential Workflow we used SequentialWorkFlowActivity. In main program we created an instance of WorkflowRuntime and using that instance we created the instance of our workflow by passing our workflow type to it. Use start() method to execute the workflow. Workflow runtime by default starts all the workflows async. in a separate thread and thats why we used the AutoResetEvent so that main program doesn't exit before our workflow gets completed.



Other Posts



* Components required to develop Workflow (WF) enabled applications

Here is a list/link to components which are required to develop/run windows workflow enabled applications :

Other Posts

Friday, February 09, 2007

* Windows Workflow Foundation (WF) : An Overview

With .NET 3.0, Microsoft released a new infrastructure for developing, deploying and maintaining workflow aware applications.

The .NET 3.0 composition can be expressed as below :

.NET 3.0 = .NET 2.0 + WCF + WPF + WF + CardSpace

WCF is Windows Communication Foundation for distributed computing, WPF is Windows Presentation Foundation for building interactive UI, WF is Windows Workflow Foundation and CardSpace is an identity management framework.

WF can be defined as a composition of the programming model, engine and tools for building workflow enabled applications for Windows platform. This is the single workflow technology which will be used by all Windows products and also custom applications build for windows platform.

As in real world, workflow in WF is also a set of activities where the control can go from one activity to another based on decisions or rules.

WF supports three kinds of workflow authoring styles :

  • Sequential : Workflow executes from start to end and can take one of the various paths based on decision rules
  • State Machine : Workflow transitions from one state to another based on events until it reaches the final state
  • Data and Rules driven

WF architecture mainly consists of following components :

  • Runtime Engine : Responsible for executing workflow in managed environment
  • Runtime Services : Responsible for scheduling, tracking, monitoring and integrating workflow with other applications
  • Base Activity Library : Set of pre-built basic libraries. Custom activities can also be developed.

In programming terms a workflow can be defined as a class in code file or defined in markup file.

 

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace HelloWorldWF
{
public partial class Workflow1 : SequentialWorkflowActivity
{
private void codeActivity1_code(object sender, EventArgs e)
{
Console.WriteLine("Hi Vikas");
}
}
}






 OR



 

<SequentialWorkflowActivity x:Class="HelloWorldWF.Workflow1" x:Name="Workflow1" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<CodeActivity x:Name="codeActivity1" ExecuteCode="codeActivity1_code" />
</SequentialWorkflowActivity>






The above workflow Workflow1 is a sequential type of workflow with only one activity called codeActivity1 which executes the method codeActivity1_code.



WF supports three kinds of authoring modes :





  1. Markup Only using XAML : where whole of the workflow definition is in the xaml file

  2. Markup + Code : where xaml contains the metadata of workflow and code contains the implementation

  3. Code Only : whole of the workflow is defined in code and is least flexible in nature


 



Other Posts