jeudi 10 avril 2008

Let the Work flows

Now

--
Alain Lompo
Excelta - Conseils et services informatiques
MCT
MCSD For Microsoft .Net
MVP Windows Systems Server / Biztalk Server
Certifié ITIL et Microsoft Biztalk Server

jeudi 20 mars 2008

Creating a simple WF activity

In this article we are going to show how to create a Windows Workflow Activity.

Our activity will be called GreetingsActivity and it has the purpose of displaying a Greetings message using the System.Console.WriteLine method.

So the best type of application in which to host the workflow containing such an activity is the Console Application template.

So let’s begin

The first thing to do is to create a library class project that you can call after the name of the Activity : GreetingsActivity. Then add all the required reference for Workflow. Create also some using statements in order to enable you to use shortcut acces to the major classes and namespaces that we will be using

using System;
using System.ComponentModel;
using System.Workflow.Activities;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;


After that I create a class which derives from System.Workflow.ComponentModel.Activity class

The main method that we are going to implement is the Execute method. We will override it in order to implement our business logic right in it.

We have also added two properties that are Greeter and Greeted, to enable the activity to receive parameters. These properties are registered through the DependencyProperty class and it’s method Register.


namespace GreetingsActivity
{
///
/// Ma première activité avec Windows Workflow Foundation
/// Il y'en aura sans doute beaucoup
///

[ToolboxItemAttribute(typeof(ActivityToolboxItem))]
public partial class GreetingsActivity:System.Workflow.ComponentModel.Activity
{
public GreetingsActivity()
{
InitializeComponent();



}

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
// Create an instance of CustomActivityEventArgs
CustomActivityEventArgs customActivityEventArgs = new CustomActivityEventArgs(this.Description);
// raise the BeforeSendEvent event and pass customActivityEventArgs
this.RaiseGenericEvent(BeforeSendEvent, this, customActivityEventArgs);

// This is where the logic of the e-mail should go
Console.WriteLine("Greetings to you all, this is my first activity");
Console.ReadKey();


return ActivityExecutionStatus.Closed;

}

// Create a DependencyProperty BeforeSendEvent and the BeforeSend event handler
public static DependencyProperty BeforeSendEvent = DependencyProperty.Register("BeforeSend", typeof(EventHandler), typeof(GreetingsActivity));

// Create some Dependency properties for the Greeter and the Greeted
public static DependencyProperty GreeterProperty = DependencyProperty.Register("Greeter", typeof(String), typeof(GreetingsActivity));
public static DependencyProperty GreetedProperty = DependencyProperty.Register("Greeted", typeof(String), typeof(GreetingsActivity));


[DescriptionAttribute("Please specify the greeter's name ")]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[ValidationOptionAttribute(ValidationOption.Optional)]
[BrowsableAttribute(true)]
public string Greeter
{
get
{
return ((String)(base.GetValue(GreetingsActivity.GreeterProperty)));
}
set
{
base.SetValue(GreetingsActivity.GreeterProperty, value);
}
}



[DescriptionAttribute("Please specify the greeted's name ")]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[ValidationOptionAttribute(ValidationOption.Optional)]
[BrowsableAttribute(true)]
public string Greeted
{
get
{
return ((String)(base.GetValue(GreetingsActivity.GreetedProperty)));
}
set
{
base.SetValue(GreetingsActivity.GreetedProperty, value);
}
}






[DescriptionAttribute("Use this Handler to do some pre-processing logic ")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[ValidationOption(ValidationOption.Optional)]
[BrowsableAttribute(true)]
[Category("Handlers")]
public event EventHandler BeforeSend
{
add
{
base.AddHandler(GreetingsActivity.BeforeSendEvent, value);
}
remove
{
base.RemoveHandler(GreetingsActivity.BeforeSendEvent, value);
}
}




}



// Create a CustomActivityEventArgs
public class CustomActivityEventArgs : EventArgs
{
public readonly string ActivityDescription;
public CustomActivityEventArgs(string activityDescription)
{
this.ActivityDescription = activityDescription;
}
}

}

Intro to WF

Windows Workflow Foundation supports multiple workflow authoring styles such as sequential, state machine, and data-driven. The sequential style is straightforward and useful for repetitive, predictable operations that are always the same, the state machine workflow style consists of a set of event-driven states, and the data-driven style relies on data to determine whether certain activities are run or not based on a local data state.

In the state machine style of workflow authoring, the author models the workflow as a state machine. The workflow itself is made up of a set of states. One state is denoted as a start state. Each state can receive a certain set of events. Based on an event a transition can be made to another state. The state machine workflow can have a final state. When a transition is made to the final state the workflow completes.The following flowchart is an example of a state machine workflow









The following table lists the state machine-related activities in the Windows Workflow Foundation framework activity set.

The following table lists the state machine-related activities in the Windows Workflow Foundation framework activity set.
Activity
Description
EventDrivenActivity
Used for states that rely on an external event to begin executing. The EventDrivenActivity must have an activity that implements the IEventActivity interface as the first child activity. For more information, see Using the EventDrivenActivity Activity.
SetStateActivity
Specifies a transition to a new state. For more information, see Using the SetStateActivity Activity.
StateActivity
Represents a state in a state machine; may contain additional State activities.For more information, see Using the StateActivity Activity.
StateInitializationActivity
Executes when a state is entered; may contain other activities. For more information, see Using the StateInitializationActivity Activity.
StateFinalizationActivity
Executes contained activities when leaving a StateActivity. For more information, see Using the StateFinalizationActivity Activity.

The sequential workflow style is straightforward and useful for repetitive, predictable operations, such as designing a set of activities to be performed in a prescribed sequence that is always the same.
The following flowchart shows a sequential workflow.



A sequential workflow executes activities in a sequential manner until the last activity completes. Sequential workflows are not necessarily entirely deterministic, even under normal operation. For example, you can use a Listen activity or a Parallel activity, and the exact sequence of events can vary in these cases.
For more information about workflow authoring, see Workflow Authoring Styles