Introducing .NET 4.0 Workflow Services
Implement WCF services using WF workflows
October 30, 2009
In this column we dive deeper into one of the majornew features in the forthcoming Windows Communication Foundation (WCF) 4.0(which will be released with Visual Studio 2010), Workflow Services. Effectively,Workflow Services let you define services where service operations, and byextension service contracts, are defined using workflow activities. For more information on Workflow Services, see "Workflow Services" and "Designing Reliable Workflow Services."
Why Workflow Services?
With Workflow Services, service definitions canprovide a level of implementation translucency not available with code, as theyare graphically defined and configured. Using workflows to implement servicesnot only makes the implementation accessible to the non-developer but alsoenables solutions to easily create a domain-specific vocabulary.
Workflow Services are built from workflows, andworkflows are assembled from components referred to as activities; the modelfundamentally encourages composition and reuse. This holds true for components thatimplement local service operations as well as for service orchestrations thatcoordinate calls across numerous remote services.
From an operations and debugging standpoint,Workflow Services delivers a win with a new unified tracing and tracking modelthat brings together WCF Tracing and Windows Workflow Foundation (WF) Tracking.This makes for a compelling service activity-monitoring experience that logsservice calls, messages, and workflow activity details directly to the EventLog via Event Tracing for Windows (ETW) or your own custom repository.
Workflow Services bring other benefits. Theirbuilt-in support for long-running processes yields a simplified asynchronousprogramming model. The enhanced performance of the workflow runtime makesworkflow-implemented services feasible even for services under demanding load.Finally, their declarative definition simplifies updates, versioning, and deploymentand even enables .config-free service endpoints.
Workflow Basics
Before delving too far into Workflow Services, ithelps to have a basic understanding of workflows. All workflows are implementedby composing activities, and the root layout that defines a workflow is itselfan activity. In Workflow Services beta 1, two workflow activities are available:Sequence and Flowchart. Sequence, as it its name implies, is a great choice forexpressing linear flows of execution.
With a Sequence, the layout of activities is rigid,flowing from top to bottom. If a loop is required, the Sequence must contain anactivity, such as a While or ForEach, that supports looping over childactivities. In other words, activities in a Sequence cannot loop back to aprevious activity.
Flowchart provides an alternative to Sequence thatsupports arbitrary loops (that is, looping back to any previous activity). Thegoal of the Flowchart is to provide a more natural diagramming approach toworkflow definition, and as such, activities in a Flowchart are free-floatingand can be arranged as desired. The flow of execution is defined by thedirected graph created by connecting activities with directional lines.
We'll explore the activities used to implement aservice using either Sequence or Flowchart shortly. For now, let's turn to theruntime aspect and understand how workflows are hosted and executed by theworkflow runtime.
Workflow Services Architecture
In .NET 3.5 you had Workflow Services, but hostingthem was like hosting ASP.NET pages without Microsoft IIS: You had to do a lotof work to implement your own hosting platform. This difficulty disappears in.NET 4.0 with the native ability to host, support, and maintain .xamlx files(the file format used by Workflow Services) in IIS and the forthcoming Dublindistributed application server.
Workflow Services are defined in XAML files thathave a .xamlx extension. These .xamlx files completely describe the workflow,its activities, and optionally any endpoints that won't be defined in a.config. If you're hosting within IIS, the experience of hosting a .xamlx isnearly identical to hosting an .svc: Your virtual directory needs to containthe .xamlx, and the bin directory contains assemblies defining any types (suchas custom activities) used by your workflow and your web.config. In theweb.config, you configure service behaviors that load extensions forpersistence (which control how your workflow is serialized to persistentstorage and removed from memory) and tracking (for defining where your servicewrites its logs as well as what it writes) and enable metadata exchange (forexposing the Web Services Description Language WSDL representing your service).
Just as for WCF Services using the ServiceHost,Workflow Services can be self-hosted in a standalone process outside of IIS by usingthe WorkflowServiceHost class. In either case, a Workflow Control Endpoint canbe enabled to provide control (e.g., creating, running, terminating) overrunning workflow instances. Dublin provides a graphical interface to thisendpoint when hosted within IIS with the Dublin extensions installed, but you'refree to implement your own UI.
Building a Workflow Service
The process of building a workflow service isdifferent from the process for implementing a traditional WCF service. Primarilythis stems from the fact that you're replacing lines of code in a serviceoperation's implementation with a composition of activities. From a high level,the differences are as follows: Service contracts are implicitly defined,service operation implementation is achieved with workflow activities, andservice definitions are completely declarative XAML files.
The steps for building a workflow service are
1. Createa new Declarative Flowchart/Sequence Workflow Service project.
2. Definea service operation:
a. Add a Receive activity and configure its inputvalue.
b. Add any activities that represent your operation'slogic.
c. Create a SendReply activity by copying from theReceive activity, and configure its return value as appropriate.
3. Repeatstep 2 for each service operation in your service.
4. Adjustservice configuration in .config, as needed.
5. Deployand host the workflow service.
To illustrate this, we'll build a simple calculatorservice containing one operation that simply takes as input two doubles andreturns a double. We begin by creating a Declarative Sequential Service Libraryproject.
Our new workflow already contains a Receiveactivity, so we just need to specify Add as the Operation Name. To specify theinput parameters for Add, we need to fill in the Value argument. From the item template's defaults, Value hasa value of data that is of type Int32. To specify a signature that containsmultiple parameters (such as our two doubles), we need to define a payload byadding a new class file to our project and declaring the DataContract asfollows:
[DataContract]public class Arguments{[DataMember]public double operand1 { get; set; }[DataMember]public double operand2 { get; set; }}
Now we need to configure the data parameter's type as Argument. To change the parameter's type,we need to first select the Sequence, then click the Variables button at the bottomleft of the workflow designer, as Figure 1 shows. From there, we can click the Variable type column, select Browse forTypes from the drop-down menu to display the type selection dialog box, andchoose Argument. (If the type isn't available under ,you may need to build your project.)
Figure 1: Defining variables scoped to the selected activity using the Variables window
To enable the calculator to perform addition, we don'tneed additional activities. Instead we'll take advantage of the expressionevaluation capability of activity arguments. For the Value argument of theSendResponse activity, we can write the following expression:
data.operand1 + data.operand2
From this, the SendReply activity will infer thatthe return type for our Add operation is of type double (and will expose it assuch in the service contract). Figure 2 shows the finished workflow.
Figure 2: Completed AdderService workflow service
Our service implementation is now complete. We cantest it easily by pressing F5, which launches the ASP.NET Development Server(WebDev.exe) and open Internet Explorer (IE) to the website hosting our .xamlx.If you navigate to the .xamlx file within IE, you'll receive the familiarservice helper page that describes the URL to use to access the service's WSDL.With this information at hand, you follow the steps you'd have followed tobuild a client of a traditional WCF service. For a quick test, you can pointWcfTestClient.exe at this URL and have it execute the addition with theparameters you supply.
Messaging Activities
Now that you've had a quick overview of how tobuild a workflow service, let's turn our attention to the activities used. Outof the box, there are six activities that play a role in defining a workflow service.The two "primitives" are Receive (for exposing a service operation)and Send (for making calls to other service operations), shown in Figure 3 andFigure 4, respectively.
Figure 3: Receive activity
Figure 4: Send activity
There are two activities for dealing with servicereplies: SendReply and ReceiveReply. SendReply, as shown earlier, is used tosend the response (such as the return value) to the caller of a serviceoperation. It's always tied to a particular Receive activity. In the case ofmaking an outgoing call using a Send activity, the workflow will get the resultof the invocation by using a ReceiveReply activity tied to the Send. Note thatneither activity appears on the toolbox. You create them by right-clicking theReceive or Send activity and choosing Copy SendReply or Copy ReceiveReply,respectively.
Because the Receive/SendReply and Send/ReceiveReplyis such a common pattern, .NET 4.0 includes two activities that define a Sequencecontaining each pair. These are the ReceiveAndSendReply and SendAndReceiveReplyactivities.
Defining Service Contracts
Workflow Services service contracts are definedimplicitly by the collection of Receive activities in a workflow and theirrespective properties. Defining an operation contract for an individual serviceoperation typically requires configuring three properties (highlighted in Figure5).
Figure 5: Key Receive activity properties used in defining a service contract
We've already reviewed OperationName. TheServiceContractName is a string that identifies the service contractimplemented by your workflow. All service operations having the same value forServiceContractName will be exposed under a contract with that name this iswhat's meant by implicit contract definition. ValueType represents the datatype of the Value property and effectively defines the signature of theparameters of the operation. Generally, configuring the Value propertyautomatically sets ValueType to the appropriate data type.
The final property of interest on the Receiveactivity is CanCreateInstance. When this property is true (checked), a newworkflow instance will be created in response to the service operationinvocation.
Beyond configuring the Receive activity, the workflow'sstructure also affects the generated service contract. If a Receive isn't pairedwith a SendReply, then it's defining a one-way service operation. If it ispaired with a SendReply, the result is a Request/Reply operation.
Defining Service Client Activities
When your Workflow Service needs to call otherservices, you can use a Send/ReceiveReply activity pair and configure theproperties manually. However there's a much easier way. Within any of the WorkflowService projects, right-click the project name, choose Add Service Reference,and point the dialog to your target service, as Figure 6 shows.
Figure 6: Using Add Service Reference
Doing so will result in the generation of a customactivity that defines the sequence prewired to call the service and expose theinput parameters and result as argument properties on the activity. Figure 7 showsthe custom activity generated when creating a service reference to the Adderservice. In addition, the client endpoint configuration needed for the servicecall will be added to an app.config in the same project. Simply build yourproject, and the custom activity will be available for immediate use in yourworkflow definitions.
Figure 7: The generated activity representing the Add operation
Service Configuration
Just as for traditional WCF services, you canseparate the configuration of a workflow service from the serviceimplementation by defining it either in an app.config (if self-hosting) or aweb.config (if hosting in IIS). That said, the .xamlx also supports putting allconfiguration XML within it and creating a config-less service.
The connection between the .xamlx workflow serviceimplementation and the corresponding service configuration in the *.config isspecified in the .xamlx's WorkflowServiceImplementation element's ConfigurationNameattribute (shown in Figure 8), which maps to *.config's service element's nameattribute (Figure 9). With this link in place, a workflow service is configuredin exactly the same fashion (using the same ServiceModel configuration section)as a traditional WCF service.
Figure 8: Excerpt of the AddService's .xamlx
Figure 9: Excerpt from the AdderService's web.config
Pairing Messages to Workflow Instances with Correlation
The problem of routing an incoming message to aparticular workflow instance is a solved by correlation. In WF 3.5, a message was routed to thecorrect workflow instance by the runtime because it contained a special headerthat contained a GUID naming the target workflow instance (known as ContextBased Correlation). WF 4 introduces a new and more flexible approach tocorrelating messages to workflow instances that can use any part of the messageby means of one or more XPATH queries, collectively referred to as aCorrelation Query.
In general, one doesn't need to bother with writingthe XPATH queries that define the correlation query; the workflow designer willbuild it provided the type of the message is known at design time. Recall thatthe message type is effectively driven by the ValueType property present on boththe Send and Receive activities. For example, if you want to correlate based onboth input operands on the Receive defining the Add operation in theAdderService, you click the ellipses next to the Correlates With property inthe property grid.
Figure 10 shows the final configuration needed tocorrelate on the values of both operands using the Correlations dialog. Youneed to specify a correlation handle variable (an opaque variable used by theworkflow to refer to correlations), a name for the correlation query, and theXPATH queries that define the correlation query. The project templateautomatically provides you with one variable "handle" scoped to thesequence to use it, just type its name into the Correlates With box. TheCorrelation Query Name is a simple string name. The Queries grid provides onerow per XPATH and allows you to provide a user-friendly name for each XPATH.
Figure 10: Correlations dialog box
To get the XPATH for an operand, click the ellipsesin the XPath column. Doing so will display the CorrelationQuery Value dialog(Figure 11). Expanding the Arguments node allows you to see the two members.Selecting one and clicking OK will insert the appropriate XPATH into the XPathcolumn.
Figure 11: CorrelationQuery Value dialog
Correlation Applied: Asynchronous Operations
Correlation makes it easy to build workflows that canmake asynchronous calls; that is, they make an outgoing service call, thenperform other work or persist waiting for the called service to return with theresult of the operation. By initializing the correlation on the Send andwaiting for the correlated value later on with the Receive (accomplished inboth cases by configuring the correlation as above), an external service cancall back into the right workflow instance. Meanwhile, the calling workflow isable to perform additional work.
Debugging and Monitoring
When building your workflow services, if you runthem via F5 they'll be hosted in the ASP.NET Development Server with the .NET 4Workflow Debugger attached. This enables you to graphically step through a workflowservice's execution, set break points, and examine workflow variable values inthe local windows. If you're attempting to debug a workflow service hosted inIIS, you can take the standard approach: Choose Attach to Process from theDebug menu and attach to the worker process (such as w3wp.exe).
What if you're trying to troubleshoot a workflow serviceto which you can't directly attach the debugger (e.g., on a production box)?This is where the new integrated ETW tracing and tracking comes into play. ETWevents are viewable from the Event Viewer, under Application and ServiceLogsMicrosoftWCFWF-Development. While you're troubleshooting, you can enablethe Debug and Analytic logs, which collectively will provide you detailedinformation ranging from the service operations invoked on the local machine,the messages logged, any exceptions thrown, and TrackingRecords emitted byworkflow execution. The latter can include logging event details for workflowstate changes, activity state changes, and user records emitted by customactivities.
Enabling ETW tracking for your workflow service isa matter of configuring a service behavior that references an ETW TrackingParticipant in the web.config. In addition, you can configure a TrackingProfile that defines filters for which workflow Tracking Records to log and, ifdesired, which workflow variable values to extract given the occurrence of aparticular tracking event. Figure 12 shows the serviceModel section for theAdderService, which enables ETW tracking with a profile that logs when theworkflow starts and ends, along with any exceptions encountered.
Figure 12: Enabling ETW tracking
Go with the Flow
I've showed you how Workflow Services provides arobust environment in which to define your services declaratively usingworkflow activities. To the outside world, they appear for all intents andpurposes like code-based services but have the readability of flow diagrams.These services can then be hosted in IIS and monitored using the Event Viewer.Now that you have an understanding of the fundamentals, you can start usingWorkflow Services and get a feel for how they'll benefit your applications.
Zoiner Tejada ([email protected]) is passionate aboutworkflow and the future of implementing connected systems with them. He's the chiefsoftware architect at Hershey Technologies, is recognized as a MicrosoftIndustry Influencer, and is an advisor to Microsoft's Connected SystemsDivision. Zoiner has a degree in computer science from Stanford University andblogs at TheWorkflowElement.com.
Read more about:
MicrosoftAbout the Author
You May Also Like