Using Custom Activities
Although it's quick and easy to use the Code activity, it's not a best practice because code directly associated with an activity is not reusable in any other workflow. When you double-click a Code activity, Visual Studio adds an event handler method directly to the workflow diagram. This is similar to double-clicking a user interface control in a Windows Forms application, which adds a handler to the parent form—but then you can use the code only in that form. It's perfectly acceptable to use the Code activity when you want to add workflow-specific code to a workflow. However, in all other cases it's best to create custom activities containing logic that you can reuse in many different workflows.
The creation and use of custom activities turns WF into a domain-specific language tool. You can create activities specific to your business domain (such as medical billing, oil and gas, financial, auto parts inventory, and so on) and then use them in multiple workflows. This is a higher and better level of abstraction in which to work.
Designing Your Workflow
In a real-world workflow, to help save time and energy, you should (call me a renegade) spend time up front designing it—determining the activities you need and the basic flow of control at a high level. The design process can be something as simple as a whiteboard drawing. You don't need to create a formal diagram because the workflow itself is a living diagram!
|Figure 8. High-Level Design: Before using the Visual Studio Workflow designer to create your workflow, it's best to create a high-level sketch outlining what you want the workflow to accomplish.|
When designing activities for your workflow, you should first determine the activity's purpose as well as its interface. It's a best practice to keep your activities self contained (not relying on other activities) so you can reuse them in any workflow.
To demonstrate these principles, you will build a sequential workflow that processes orders. As already mentioned, you should first create a high-level overview of what you want the workflow to accomplish. Figure 8 provides just that.
The high-level "sketch" in Figure 8 shows the different activities that the workflow needs to perform as well as the basic flow of the business process in flowchart format. As you can see, the workflow first validates the customer to determine if that customer can order products (the customer may be over a credit limit). If they can't order, the program sends an e-mail to them rejecting their order. If the customer can order, the workflow validates each product to see if it's available. If the product is available, it's added to their order; otherwise, it's backordered. When finished, the workflow sends an email invoice to the customer and marks the order for shipment.
Creating Custom Activities
Here's how the sketch in Figure 8 translates into a WF diagram. The rounded rectangles in the sketch in Figure 8 all translate into activities in a workflow. The decision and flow-of-control elements also easily map to elements in WF. So, first, create an activity that validates the customer.
|Figure 9. New Default Activity: By default, activities are based on the Sequential activity which can contain multiple child activities.|
Right-click your workflow project, and select Add → New Item from the shortcut menu. In the Add New Item dialog box, select Activity. In the Name text box, change the name of the activity to ValidateCustomerActivity.cs
). Finally, click Add to add the new activity to Solution Explorer. You'll see a visual representation of the activity as shown in Figure 9
. Notice the new activity contains the name of the activity as well as the text "Drop activities here." This is because, by default, Visual Studio derives new activities from the WF SequenceActivity class, which can contain child activities.
|Author's Note: It's a standard naming convention to use the suffix "Activity" on all your WF activities.
In this case, because the activities in this workflow don't need to contain child activities, you can change the base class of the activity to System.Workflow.ComponentModel.Activity instead. To do this, select the new custom activity in design mode, go to the Properties window, and then select the Base Class property. Click the ellipsis button associated with the property, which launches the "Browse and Select a .NET Type" dialog box. In the left pane of the dialog box, select the System.Workflow.ComponentModel node. In the right pane of the dialog box, select the Activity class as shown in Figure 10
, and then click OK. This sets the base class of the custom activity to Activity and changes the design-time appearance of the activity so it no longer indicates that you can add child activities to it as shown in Figure 11
|Figure 10. Changing the Base Class: You can easily change the base class of an activity by modifying its Base Class property.||
|Figure 11. The Activity Base Class: Changing an activity's base class to Activity removes the option to add children, which is often what you want for your custom activities.||
Next, go to the Solution Explorer and rename the Workflow1.cs
) file to ProcessOrderWorkflow.cs
Select Yes in the dialog box that asks if you want to rename all project elements.
Now rebuild your project. Afterward, double-click the ProcessOrderWorkflow diagram in the Solution Explorer to display it in design mode. The Workflow Toolbox should now contain your custom activity as shown in Figure 12.
|Figure 12. Custom Activity: Visual Studio automatically displays your custom activities in the Toolbox for easy access.|
In contrast to the generic WF activities that come out of the box, you are creating activities specific to a particular domain—order processing.