Creating a Workflow Foundation Custom Activity with Activity Derivation

Activity derivation is one of the two methods to create Custom Activities. Unlike the composition (the another method), where with several basic activities we can create a new large and complex activity, on this method we focus on creating one single activity, defining their properties and execution model. Let's look at an example of an activity created by this method, wich will be aiming to display a message on the console.

To do that we must create a new project of Workflow Activity Library type. We will name it 201CWFActivityDerivation201D. and add a new class called ActivityDerivationExample.cs, which the following code:

public class ActivityDerivationExample : Activity

{

A0A0A0 string _text;

A0

A0A0A0 public string Text

A0A0A0 {

A0A0A0A0A0A0A0 get { return _text; }

A0A0A0A0A0A0A0 set { _text = value; }

A0A0A0 }

A0

A0A0A0 protected override ActivityExecutionStatus Execute(

A0A0A0 ActivityExecutionContext executionContext)

A0A0A0 {

A0A0A0A0A0A0A0 Console.WriteLine(Text);

A0A0A0A0A0A0A0 Console.ReadKey();

A0A0A0A0A0A0A0 return ActivityExecutionStatus.Closed;

A0A0A0 }

}

The class inherits from System.Workflow.ComponentModel.Activity, which is the base of all activities in WF. Our example activity exposes a property called 201CText201D whose value can be set from the workflow designer and which will be displayed on the console when the activity run.

The main feature of this class is the Execute method. When we override this method we are assuming full responsability for the behavior of the activity. When the time comes to execute our custom activity, WF runtime will invoke our Execute method and then show our message on the console. After that we need to tell the WF runtime that our activity execution has ended, returning the value Closed of the ActivityExecutionStatus.

At this point we can build our activity and create the assembly for distribution.

A0

Activity Designers:

The Activity Designers are used to control the appearance of the activities at design time. To create a designer we need a new class that inherits from ActivityDesigner and override their virtual methods. The following example shows how to override the method OnPaint, who draws our activity in the designer's workflow:

public class ActivityDerivationDesigner : ActivityDesigner

{

A0A0A0 ActivityDerivationExample _activity;

A0A0A0 protected override void Initialize(Activity activity)

A0A0A0 {

A0A0A0A0A0A0A0 _activity = activity as ActivityDerivationExample;

A0A0A0A0A0A0A0 base.Initialize(activity);

A0A0A0 }

A0

A0A0A0 protected override void OnPaint(ActivityDesignerPaintEventArgs e)

A0A0A0 {

A0A0A0A0A0A0A0 e.Graphics.FillRectangle(Brushes.Black, Location.X, Location.Y, Size.Width, Size.Height);

A0A0A0A0A0A0A0 Rectangle rect = new Rectangle(Location.X, Location.Y, Size.Width, 15);

A0A0A0A0A0A0A0 Font font = new Font("Lucida Console", 8);

A0A0A0A0A0A0A0 e.Graphics.DrawString(@"C:\> " + _activity.Text, font, Brushes.White, rect.X, rect.Y + 10);

A0

A0A0A0 }

}

The following syntax is used to associate the designer to our activity::

//ActivityDerivationExampe.cs

[Designer(typeof(ActivityDerivationDesigner))]

public class ActivityDerivationExample : Activity

{

A0A0A0 //

}

A0

With this, our activity will looks like the following picture:

image

A0

Activity Validators:

The Activity Validators run at design and build time, and are used to ensure that the activity has the correct settings to run. To create a validator need a new class that inherits from the class ActivityValidator and overwrite method Validate.
For example the following validator will ensure that our activity has a valid value in the Text property:

public class ActivityDerivationValidator : ActivityValidator

{

A0A0A0 public override ValidationErrorCollection Validate(ValidationManager manager, object obj)

A0A0A0 {

A0A0A0A0A0A0A0 ValidationErrorCollection errors = base.Validate(manager, obj);

A0A0A0A0A0A0A0 ActivityDerivationExample activity = obj as ActivityDerivationExample;

A0A0A0A0A0A0A0 if (activity.Parent != null && String.IsNullOrEmpty(activity.Text))

A0A0A0A0A0A0A0 {

A0A0A0A0A0A0A0A0A0A0A0 errors.Add(ValidationError.GetNotSetValidationError("Text"));

A0A0A0A0A0A0A0 }

A0A0A0A0A0A0A0 return errors;

A0A0A0 }

}

All validation errors are added to the ValidationErrorCollection collection and returned to the caller.

The following syntax is used to associate the validator to our activity:A0

//ActivityDerivationExampe.cs

[ActivityValidator(typeof(ActivityDerivationValidator))]

public class ActivityDerivationExample : Activity

{

A0A0A0 //

}

A0

Conclusion:

The Activity Derivation allow us to create new activities that inherits from the base class Activity. You can also inherits from other classes that implement Activity, to use more features. This method gives us the highest level of control and offers us a way to extend WF code itself.

1 Comment

Comments have been disabled for this content.