Walkthrough: Implementing a Service by Using a State Machine Conversational Workflow
This walkthrough creates a state machine-based conversational workflow operation. This operation models a simple order processing service. The first phase of the conversation receives order information and generates an OrderId. The second phase accepts the OrderId and returns an order placement confirmation message. The state machine contains a state for each phase of the conversation and a completed state.
The process for building a state machine workflow differs from the process for building sequential workflows only at the point where you implement the workflow. This walkthrough assumes that you have previously created the Message classes and BLSpecific project to use for implementing the workflow.
Before you begin
- Create a DCS Solution project in Visual Studio named OrderProcessing. For detailed instructions, see Walkthrough: Creating a DCS Solution.
- Create a Messages project in the DCS Solution project named OrderProcessingMessages. Create the project in the OrderProcessingNamespace.Messages namespace. For detailed instructions about how to create a Messages project, see Walkthrough: Creating a DCS Messages Project.
- Create the PlaceOrderRequest, PlaceOrderResponse, ConfirmOrderRequest, and ConfirmOrderResponse, OrderProcessingError, and OrderProcessingException classes for the conversational workflow, and create the BL Specific project to implement the workflow in. For detailed instructions, see Walkthrough: Implementing a Service by Using a Sequential Conversational Workflow.
Detailed Instructions
To create a state-machine conversational workflow operation
In Solution Explorer in Visual Studio, right-click the OrderProcessingBLSpecific project, and then click AddNew Operation State Workflow.
In the Add New Operation State Workflow dialog box on the Operation Configuration page, in the Operation Name field, type PlaceOrderSM, and then click Next.
The following image shows the Operation Configuration page.
The Operation Configuration page of the Add New Operation State Workflow dialog box, configured to create a new operation named PlaceOrderSM.
On the Messages Selector page, click ellipsis button (…) adjacent to the Select type of Request message field.
In the Please choose a file dialog box, browse to the E:\Walkthroughs\OrderProcessing\Messages\OrderProcessingMessages\bin\Debug folder, click OrderProcessingMessages.dll, and then click Open.
In the Add New Operation Request/Response dialog box on the Messages Selector page, configure the operation messages as follows, and then click Next:
-
Select type of Request message: PlaceOrderRequest
Select type of Response message: PlaceOrderResponse
Select type of Error: OrderProcessingError
Select type of Exception: OrderProcessingException
-
Note
When you first create the conversational workflow operation, specify the messages that make up the first phase of the operation. You will add properties and functionality to the workflow itself to enable further conversation phases.
The following image shows the Messages Selector page.
The Messages Selector page of the Add New Operation State Workflow dialog box, configured to set the new operation Request message to PlaceOrderRequest, and the Response message to PlaceOrderResponse
On the Messages Assemblies References page, in the AssembliesReferences list, make sure that the OrderProcessingMessages (Project) item is selected, and then click Finish.
The following image shows the Messages Assemblies References page.
The Messages Assemblies References page of the Add New Operation Request/Response dialog box.
To implement conversational workflow functionality
In Solution Explorer, in the OrderProcessingBLSpecific project, in the PlaceOrderSM folder, right-click PlaceOrderSMWorkflow.cs, and then click View Code.
Expand the Properties accessor code region, and add code to the region to create local instances of the ConfirmOrderRequest and ConfirmOrderResponseMessage classes. You can follow the format used to define the existing Request and Response properties.
-
Note
Creating these properties in the code-behind file lets you configure the WaitForEvent and SendResponse activities to use the correct messages for each phase of the conversation.
Your code should resemble the following example.
-
#region Properties accessor... ... private OrderProcessingNamespace.Messages.ConfirmOrderRequest _ConfirmRequest; public OrderProcessingNamespace.Messages.ConfirmOrderRequest ConfirmRequest { get { return _ConfirmRequest; } set { _ConfirmRequest = value; } } private OrderProcessingNamespace.Messages.ConfirmOrderResponse _ConfirmResponse; public OrderProcessingNamespace.Messages.ConfirmOrderResponse ConfirmResponse { get { return _ConfirmResponse; } set { _ConfirmResponse = value; } } #endregion
In Solution Explorer, right-click PlaceOrderSMWorkflow.cs, and then click View Designer.
From the Toolbox, in the Windows Workflow section, drag a State activity onto the workflow designer and drop it in the top left corner.
In the Properties window, change the (Name) property of this activity to placeOrderState.
Repeat steps 4 and 5 to add states named confirmOrderState and completedState.
Right-click the placeOrderState activity, and then click Set as Initial State.
Right-click the completedState activity, and then click Set as CompletedState.
From the toolbox, drag a StateInitialization activity on to the workflow designer and drop it inside the placeOrderState activity.
Change the (Name) property to placeOrderFunctionality, and then double-click the activity to open the activity designer.
From the Toolbox, drag a Code activity onto the designer surface, and drop it inside the placeOrderFunctionality activity.
Change the (Name) property to placeOrder, and then double-click the activity to create an event handler in the code-behind file.
In the placeOrder_ExecuteCode method, add a line of code to set the Response.OrderId property to 1.
Your code should resemble the following example.
-
private void placeOrder_ExecuteCode(object sender, EventArgs e) { this.Response.OrderId = 1; }
-
Note
This code simulates sending the order data to a database and retrieving an automatically generated order number.
Switch to the workflow designer.
From the toolbox, in the DCS group, drag a SendResponse activity onto the designer surface, and drop it below the placeOrder activity.
Change the activity (Name) property to sendPlaceOrderResponse.
Bind the activity Response property to the workflow Response property:
-
- In the Properties window, click the Response property, and then click the ellipsis button (…) that appears.
- In the Bind 'Response' to an activity's property dialog box, on the Bind to an existing member tab, click Response, and then click OK.
Set the SpawnNewThread property to True.
From the Toolbox, in the Windows Workflow group, drag a SetState activity onto the designer surface, and drop it below the SendPlaceOrderResponse activity.
Change the (Name) property to setConfirmOrderState, and then change the TargetStateName to confirmOrderState.
Your activity should resemble the following image.
A state-machine workflow containing a Code activity, a SendResponse activity, and a SetState activity
Click PlaceOrderSMWorkflow to return to the workflow designer.
From the Toolbox, drag an EventDriven activity onto the designer surface, and drop it inside the confirmOrderState activity.
Change the (Name) property to onConfirmOrderEventReceived, and then double-click the activity to open the activity designer.
From the Toolbox in the DCS Section, drag a WaitForEvent activity onto the activity designer, and drop it in the onConfirmOrderEventReceived activity.
Change the (Name) property to waitForConfirmOrderEvent, and change the Action property to ConfirmOrder.
Change the InputType property to OrderProcessingNamespace.ConfirmOrderRequest.
-
Click the InputType property, and then click the ellipsis button (…) that appears.
In the Browse and Select a .NET Type dialog box, in the Type list, click OrderProcessingMessages.
Under Type Name, click ConfirmOrderRequest, and then click OK.
The following image shows the Browse and Select a .NET Type dialog box.
The Browse and Select a .NET Type dialog box configured to select the ConfirmOrderRequest message from the OrderProcessingMessages assembly
Bind the InputData property to the workflow ConfirmRequest property.
-
- Click the InputData property, and then double-click the Bind Data icon.
- In the Bind 'InputData' to an activity's property dialog box, on the Bind to an existing member tab, click ConfirmRequest, and then click OK.
Change the ResponseType property to OrderProcessingNamespace.ConfirmOrderResponse.
-
- Click the ResponseType property, and then click the ellipsis button (…) that appears.
- In the Browse and Select a .NET Type dialog box, in the Type list, click OrderProcessingMessages.
- Under Type Name, click ConfirmOrderResponse, and then click OK.
Change the WithResponse property to True.
From the Toolbox, drag a Code activity onto the activity designer, and drop it in the onConfirmOrderEventReceived activity under the waitForConfirmOrderEvent activity.
Change the (Name) property to confirmOrder, and then double-click the activity to create an event handler in the code-behind file.
In the confirmOrder_ExecuteCode method, add code to set the ConfirmResponse property to a new instance of the OrderProcessingNamespace.Messages.ConfirmOrderResponse class, and then check whether the ConfirmRequest.OrderId value matches the Response.OrderId value. If the values match, set the ConfirmResponse.OrderPlaced value to true; otherwise, set it to false.
Your code should resemble the following example.
-
private void confirmOrder_ExecuteCode(object sender, EventArgs e) { ConfirmResponse = new OrderProcessingNamespace.Messages.ConfirmOrderResponse(); if (Response.OrderId == ConfirmRequest.OrderId) ConfirmResponse.OrderPlaced = true; else ConfirmResponse.OrderPlaced = false; }
-
Note
This code simulates confirming the order in the database. If the client application changes the OrderId value between calls to the service, the response is false; otherwise, the response is true.
Switch to the workflow designer.
From the toolbox in the DCS group, drag a SendResponse activity onto the designer surface, and drop it below the confirmOrder activity.
Change the (Name) property to sendConfirmOrderResponse, and set the RelatedActivity property to waitForConfirmOrderEvent.
Bind the Response property to the workflow ConfirmResponse property.
-
- Click the Response property, and then click the ellipsis button (…) that appears.
- In the Bind 'Response' to an activity's property dialog box, on the Bind to an existing member tab, click ConfirmResponse, and then click OK.
Set the SpawnNewThread property to True.
From the Toolbox, drag a SetState activity onto the workflow surface, and drop it below the sendConfirmOrderResponse activity.
Change the (Name) property to setCompletedState, and then change the TargetStateName to completedState.
Your activity should resemble the following image.
A state-machine workflow implementation containing a WaitForEvent activity, a Code activity, a SendResponse activity, and a SetState activity
Save the workflow and build the project. Verify that there are no errors.
You have now implemented the conversational workflow. However, by default the stub generated for this workflow only exposes the initial PlaceOrderSM operation in the conversation, and not the operation that enables the client application to invoke the ConfirmOrder operation. To expose the ConfirmOrder operation, you use the Update Stub and Operations recipe. For detailed instructions, see Walkthrough: Implementing a Service by Using a Sequential Conversational Workflow.
After you generate the required event code to enable a client application to invoke each stage in the conversation, you can deploy the service and begin building the client application.
Note
When you build the client application for this service, you must use the same Context object each time that the client application calls the service to make sure that DCS correlates messages and operations correctly.
You can build services that use different mechanisms to correlate requests made by client applications to a specific service instance. For more information, see How DCS Implements Services and Operations.
For more information about deploying services, see Walkthrough: Deploying DCS Services by Using Visual Studio. For more information about building client applications, see Building Client Applications.
See Also
Walkthrough: Creating a DCS Solution
Walkthrough: Creating a DCS Messages Project
Walkthrough: Implementing a Service by Using a Sequential Conversational Workflow
How DCS Implements Services and Operations