Now that the essentials of the state-machine workflow type have been introduced, it’s time to cover the development of state-machine workflows in the Windows Workflow Foundation designer. Because state-machine workflows are different from sequential workflows, this workflow type has its own distinct designer.
Figure 10-3 shows an example of the state-machine workflow designer with a completed workflow. This example showcases a workflow modeling the process of a party. There is an initial state called Party WorkflowInitialState that transitions to EntertainingState when the OnFirstGuestArrival EventDriven activity is executed. If the food runs out during the EntertainingState, the workflow transitions to the PreparingRefreshmentsState. When the refreshments are ready, the workflow returns to the EntertainingState. When the party is active, guest arrivals are captured by the OnGuestArrives EventDriven activity. Finally, if at any time during the EntertainingState or PreparingRefreshmentsState the last guest leaves, the workflow transitions to the PartyOver state, signifying the end of the party workflow.
There are a few interesting things about the designer in this example. First, take a look at the Party WorkflowInitialState State activity. This state is the workflow’s initial state, and as such, it has a special green icon on the top left. In addition, the PartyOver state is the workflow’s completed state. This state has a special icon as well, denoted by the red image at its upper left. Remember, these two special states are configured by setting the InitialStateName and CompletedStateName properties of the workflow itself.
The state-machine workflow designer also provides a context menu where you can set these properties. Figure 10-4 shows the context menu that is displayed when you right-click a State activity in the designer. The Set As Initial State and Set As Completed State menu options provide an easy way to manipulate certain workflow properties.
This context menu also provides other options for manipulating the definition of a state-machine workflow. In this example, there are four options to add context-appropriate activities to the selected State activity (the activity that was previously selected by right-clicking it in the designer). In this case, the activities that can be added are State, EventDriven, StateInitialization, and StateFinalization. If you right-click an empty area of the workflow itself, you are presented with a set of options to add State and EventDriven activities. Using the context menu to add activities yields the same results as dragging and dropping an activity from the Visual Studio Toolbox.
Drilling down, the designer view in Figure 10-5 shows the detail behind an EventDriven activity. In this case, the EventDriven activity shown is OnFirstGuestArrival, which is located in PartyWorkflow InitialState. This view was accessed by double-clicking the OnFirstGuestArrival EventDriven activity in the main workflow designer, as signified by the breadcrumb trail at the top of the designer. This shows that the current view is inside PartyWorkflowInitialState, which is inside Party Workflow. If you click an item in a breadcrumb trail, you are taken to whatever view is appropriate. This is a convenient way to navigate the workflow.
Remember that the first activity in an EventDriven activity has to implement IEventActivity, which the HandleExternalEvent activity does. The first activity in the example EventDriven activity is handleGuestArrivesEvent, which waits until a guest arrives to execute the next activities. There is also a Code activity that simply increments a workflow variable (in this case, keeping track of the number of guests). Last in the execution chain is a SetState activity. The setEntertainingState State activity specifies that the workflow should transition to EntertainingState at this point. Because this activity is configured to make the appropriate transition, the workflow designer automatically displays an arrow going from the EventDriven activity to the appropriate state, as shown in Figure 10-6.
The EventDriven activity view displayed in Figure 10-5 shows the OnGuestLeaves EventDriven activity, which is defined in PartyActiveState. This activity is a little more interesting because there is logic that checks the guest count variable to whether if there are any guests left when one leaves. If, and only if, the last guest just left, the workflow transitions to the PartyOver state. Because the PartyOver state is designated at the completed state of the workflow, the execution of the instance ends when a transition moves to that state. Notice in Figure 10-6 that an arrow is drawn from the OnGuestLeaves EventDriven activity to the PartyOver state even though the transition is conditional and does not always occur.
As previously mentioned, if you have correctly configured the SetState activities, the state-machine workflow designer uses arrows to help you visualize these transitions. However, you can automate adding and configuring these SetState activities by simply clicking an anchor on an EventDriven activity and dragging it to an anchor on a State activity. After you perform this action in the designer, you can inspect the EventDriven activity view of the activity from which you dragged the anchor and see that a SetState activity has been added for you. In addition, the TargetStateName property is set to point to the chosen State activity.