Browse DevX
Sign up for e-mail newsletters from DevX


Windows Workflow Foundation Essentials : Page 4

Applications that contain business processes and rules can benefit immediately from Windows Workflow's diagrams, class libraries, runtime, rules engine, and customization capabilities.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Workflow and Business Objects
At this point the custom activity doesn't do anything. The ValidateCustomerActivity needs to validate that a customer can order products (for example, by ensuring that a customer has not exceeded a credit limit). Rather than placing this code directly in the custom activity, you can put the code in a business object, which is preferable because it allows you to use the same core business logic outside the context of WF. As shown in Figure 13, the workflow can call the services of an activity and, in turn, the activity can call the services of one or more business objects.

Figure 13. Calling External Code: Rather than placing all your code in Workflow activities, you can have activities call services of business objects which can be reused outside the context of Windows Workflow.
The sample code for this article contains a business object project that contains very rudimentary business objects. In fact, most of the business object's methods contain pseudo-code, but overall, they can give you a clear picture of WF best practices.

If you are following the step-by-step instructions in this article, you need to add the Order System Business Objects project to your SequentialWorkflowConsole solution. After downloading the sample code, right-click the SequentialWorkflowConsole solution in the Solution Explorer, and then from the shortcut menu select Add → Existing Project. Navigate to the sample project and add the existing Order System Business Objects project to your solution. To reference the business objects from the Workflow project, right-click the SequentialWorkflowConsole project and select Add Reference from the shortcut menu. In the Add Reference dialog box, select the Projects tab, select the Order System Business Objects project, and then click OK.

Enhancing Custom Activities
Now you're ready to enhance the custom activity so it performs some real work. The main purpose of the ValidateCustomerActivity activity is to verify that a customer can order products. The key input this activity needs is the ID of the customer being validated. As output, the activity produces a Boolean value indicating whether the customer can order products. The best way to pass this information to and from the activity is by means of dependency properties.

In Windows Workflow a dependency property is similar to a regular .NET property, but rather than storing its value in a private variable, the workflow runtime stores the value in a dictionary maintained by the workflow. This dictionary lets the Workflow automatically propagate the value of the dependency properties to other activities or to the workflow itself, a process known as activity data binding. Activity data binding helps you create encapsulated activities—because they read and write only to their own properties and don't directly access the workflow or other activities (and therefore don't have a strong dependency on them), which makes the activity reusable in multiple workflows.

Figure 14. Adding Code Snippets: The Workflow Extensions for Visual Studio 2005 add two code snippets that simplify creating dependency properties and their event handlers.
To create a dependency property for the ValidateCustomerActivity that stores the Customer ID as input, right-click the activity in the Solution Explorer and select View Code from the shortcut menu. Add a new, empty line near the top of the class definition, and type the characters wpd. If you have installed the Visual Studio 2005 extensions for Windows Workflow, typing these characters should display the IntelliSense window with the code snippet selected for creating a dependency property as shown in Figure 14. If you are using C#, press TAB twice (just once if using Visual Basic) to insert the snippet code. In the first code snippet box, type CustomerID as the name of the dependency property. Tab to the next code snippet box (tab twice in VB), and type int (C#) or Integer (VB) as the type of the dependency property. If using VB, you must press Tab again and enter the name of the activity class, which in this case is ValidateCustomerActivity.

Next, tab down to the dependency property description and enter Customer ID. Tab again to enter the next code snippet box, and enter Custom Property as the dependency property category. If you are using C#, press Enter to finish editing the code snippet (for some reason this keystroke doesn't work with VB snippets).

When you're finished, your dependency property should look like this in C#:

public static DependencyProperty CustomerIDProperty = System.Workflow.ComponentModel. DependencyProperty.Register( "CustomerID", typeof(int), typeof(ValidateCustomerActivity)); [Description("Customer ID")] [Category("Custom Property")] [Browsable(true)] [DesignerSerializationVisibility( DesignerSerializationVisibility.Visible)] public int CustomerID { get { return ((int)(base.GetValue( ValidateCustomerActivity. CustomerIDProperty))); } set { base.SetValue(ValidateCustomerActivity. CustomerIDProperty, value); } }

And like this in Visual Basic:

Public Shared CustomerIDProperty As _ DependencyProperty = DependencyProperty.Register( _ "CustomerID", GetType(Integer), GetType( _ ValidateCustomerActivity)) <Description("Customer ID")> _ <Category("Custom Property")> _ <Browsable(True)> _ <DesignerSerializationVisibility( DesignerSerializationVisibility.Visible)> _ Public Property CustomerID() As Integer Get Return (CType((MyBase.GetValue( _ ValidateCustomerActivity. _ CustomerIDProperty)), Integer)) End Get Set(ByVal Value As Integer) MyBase.SetValue(ValidateCustomerActivity. _ CustomerIDProperty, Value) End Set End Property

Note that the Get() and Set() methods of the properties do not retrieve or store values into a private variable. Instead, they call the GetValue() and SetValue() methods on the Activity base class, which stores the value in a dictionary object maintained by the workflow.

You also need to create a dependency property that can hold the Boolean output value of the customer validation. To do this, use the wdp code snippet again to create a second dependency property, but this time name the property CanCustomerOrderProperty, make it of type Boolean, set the description to "Specifies if the customer can order a product," and set the category to Custom Property. Your dependency property should look like this in C#:

public static DependencyProperty CanCustomerOrderProperty = System.Workflow.ComponentModel.DependencyProperty. Register("CanCustomerOrder", typeof(Boolean), typeof(ValidateCustomerActivity)); [Description("Specifies if the customer can order product")] [Category("Custom Property")] [Browsable(true)] [DesignerSerializationVisibility( DesignerSerializationVisibility.Visible)] public Boolean CanCustomerOrder { get { return ((Boolean)(base.GetValue( ValidateCustomerActivity. CanCustomerOrderProperty))); } set { base.SetValue(ValidateCustomerActivity. CanCustomerOrderProperty, value); } }

And like this in Visual Basic:

Public Shared CanCustomerOrderProperty As _ DependencyProperty = DependencyProperty. _ Register("CanCustomerOrder", GetType(Boolean), _ GetType(ValidateCustomerActivity)) <Description("Specifies if the customer can order " & _ "product")> _ <Category("Custom Property")> _ <Browsable(True)> _ <DesignerSerializationVisibility( DesignerSerializationVisibility.Visible)> _ Public Property CanCustomerOrder() As Boolean Get Return (CType((MyBase.GetValue( _ ValidateCustomerActivity. _ CanCustomerOrderProperty)), Boolean)) End Get Set(ByVal Value As Boolean) MyBase.SetValue(ValidateCustomerActivity. _ CanCustomerOrderProperty, Value) End Set End Property

Thanks for your registration, follow us on our social networks to keep up-to-date