Workflow Foundation 4.0 is introduced a significant amount of change from the previous versions of the technology. This article will be the first in a series of articles. In this article I will be discussing about the introduction to Custom Activity Development. In next articles, I will be concentrating more on the different aspects of Custom Activity Development.
Custom Activity
WF4.0 supports the custom activity development. Custom Activity development involves two parts- designer development and execution logic implementation. I already discussed about the designer development in Activity Designer in Workflow Foundation 4.0 article.
Part I : Introduction to Custom Activity Development
Part II : Bookmark
For developing the custom activity, you need to inherit from
NativeActivity – base class of custom activities, which can have full control on runtime features.
Code Activity- base class of custom activities, which don’t have access to runtime features.
AsynchCodeActivity – Asynchronous Code execution
Also, we have NativeActivity<T>, CodeActivity<T> and AsynchCodeActivity<T> base classes.
In our sample custom activity, we will use the NativeActivity as base class
public class SampleCustomActivity:NativeActivity
{
protected override void Execute(NativeActivityContext context)
{
throw new NotImplementedException();
}
}
How to Link Designer to the Activity?
As I specified, activity designer is created separately using WPF. For binding the activity designer to the custom activity, we can use the following attribute on top of the activity
[Designer(typeof(ActivityDesigner.SampleCustomActivityDesigner))]
public class SampleCustomActivity:NativeActivity
How to Prevent the expand/collapse nature?
Drag our custom activity to the workflow designer and double click on the activity; it will expand to the next level. The built-in activities, like WriteLine, Delay and Assign, doesn’t have expand and collapse behavior. If we need to implement the same behavior for our custom activity, which is not a container activity for other activities, use the following attribute
[ActivityDesignerOptions(AllowDrillIn = false)]
[Designer(typeof(ActivityDesigner.SampleCustomActivityDesigner))]
public class SampleCustomActivity:NativeActivity
How to pass data to the Activity?
For passing data to the Activity, either we can use the InArguments or class level Properties. InArguments are special type of properties used for passing data to the Activity. InArguments is related to an instance of the Activity and it required the particular activity instance’s context for accessing the data from InArgument. In the following Code we are defining an InArgument of type string with name Message
public class SampleCustomActivity:NativeActivity
{
public InArgument<string> Message{get;set;}
protected override void Execute(NativeActivityContext context)
{
throw new NotImplementedException();
}
}
When you drag and drop the custom activity to workflow designer, you can see the InArgument in the property grid.
We can get the value of the InArgument using any of the following statements. Variables message and message2 will contain the same value.
protected override void Execute(NativeActivityContext context)
{
string message = Message.Get(context);
string message2=context.GetValue(Message);
}
How to pass data out of the Activity?
There are multiple ways to pass data from an activity to other activities or workflow. In the first example, we are defining an activity, which can return only one value. If an activity needs to return, only a single value, then inherit it from CodeActivity or NativeActivity or AsynchCodeActivity.
Once you derive the custom activity from any of these classes, it defines an OutArgument with name as Result. We can set the value of this built-in OutArgument as specified below
public class SampleCustomActivity:NativeActivity<string>
{
public InArgument<string> Message { get; set; }
protected override void Execute(NativeActivityContext context)
{
string message = Message.Get(context);
Result.Set(context,"Message from Custom Activity " + message);
//context.SetValue(Result, "Message from Custom Activity " + message);
}
}
How to access the OutArgument Outside?
Following picture shows, how we can access the OutArgument from outside the custom activity. Define a variable, which can hold the OutArgument; specify the same against the OutArgument in the property grid; use the variable in another activity.
This is the simple way of communication between activities or activity to host. There are other ways of communication using Extension methods, Workflow Properties, Bookmarks, WCF Services, etc.
How to define an OutArgument?
OutArgument is used for passing data out of an activity. We can define our own OutArguments as specified below
public class SampleCustomActivity:NativeActivity
{
public InArgument<string> Message { get; set; }
public OutArgument<string> MessageFromActivity { get; set; }
protected override void Execute(NativeActivityContext context)
{
string message = Message.Get(context);
context.SetValue(MessageFromActivity, "Message from Custom Activity " + message);
}
}
Conclusion
Here, we discussed about the custom activity development in Windows Workflow Foundation 4.0. This is an introduction to the custom activity development. In next articles, we will discuss more on the custom activity development and associated topics.