Mariano@Blog!

.NET and other interesting stuff.

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 “WFActivityDerivation”. and add a new class called ActivityDerivationExample.cs, which the following code:

public class ActivityDerivationExample : Activity

{

    string _text;

 

    public string Text

    {

        get { return _text; }

        set { _text = value; }

    }

 

    protected override ActivityExecutionStatus Execute(

    ActivityExecutionContext executionContext)

    {

        Console.WriteLine(Text);

        Console.ReadKey();

        return ActivityExecutionStatus.Closed;

    }

}

The class inherits from System.Workflow.ComponentModel.Activity, which is the base of all activities in WF. Our example activity exposes a property called “Text” 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.

 

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

{

    ActivityDerivationExample _activity;

    protected override void Initialize(Activity activity)

    {

        _activity = activity as ActivityDerivationExample;

        base.Initialize(activity);

    }

 

    protected override void OnPaint(ActivityDesignerPaintEventArgs e)

    {

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

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

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

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

 

    }

}

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

//ActivityDerivationExampe.cs

[Designer(typeof(ActivityDerivationDesigner))]

public class ActivityDerivationExample : Activity

{

    //

}

 

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

image

 

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

{

    public override ValidationErrorCollection Validate(ValidationManager manager, object obj)

    {

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

        ActivityDerivationExample activity = obj as ActivityDerivationExample;

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

        {

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

        }

        return errors;

    }

}

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: 

//ActivityDerivationExampe.cs

[ActivityValidator(typeof(ActivityDerivationValidator))]

public class ActivityDerivationExample : Activity

{

    //

}

 

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.

Posted: Nov 02 2007, 04:09 PM by MarianoS | with 1 comment(s) |
Filed under:

Comments

Ganesh said:

This is Really Great.

But if i apply this to state acticity then it does not work

Please Help me........

# June 17, 2009 7:38 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)