Workflow Services
Exploring .NET Framework 3.5 Features for Better Workflow and WCF Integration
October 30, 2009
Exploring WCF Web Services
LANGUAGES:C#
TECHNOLOGIES:.NET 3.5 | WCF
Workflow Services
Exploring .NET Framework 3.5 Features for BetterWorkflow and WCF Integration
By Michele Leroux Bustamante
This monthly column explores how to expose workflows as WCFservices, and how to consume WCF services from workflows using featuresintroduced with .NET Framework 3.5. If you have questions about migrating yourexisting ASMX or WSE Web services to WCF, or questions regarding WCF as itrelates to Web services, please send them to [email protected]!
Workflow Services were introduced with the release of .NETFramework 3.5 to facilitate better communication between WCF and WindowsWorkflow Foundation (Workflow or WF). Before this release it was cumbersome atbest to start a workflow from a WCF service operation, or to call a WCF serviceoperation from an executing workflow. The term Workflow Services describes aworkflow that is exposed as a WCF service and can more easily make calls toother WCF services, thanks to a few new Workflow activities: ReceiveActivityand SendActivity. Visual Studio templates simplify the process of creating anew Workflow Service by generating sample sequential or state machine workflowsalong with related code and configuration.
In this article I ll explain how Workflow Services can beused to expose workflows as WCF services, and to consume other WCF services and why you would want to leverage these features. I assume you have some basicunderstanding of Workflow technology, so I won t be introducing you to Workflowconcepts.
Why Workflow Services?
Workflow is useful for describing and executinglong-running and complex business processes. Typically, we see Workflow technologyimplemented as part of the middle-tier to automate the flow of messagingbetween users, applications, and services. For client applications to reach aworkflow, it is helpful to expose it as a WCF service either behind thefirewall or on the Internet. In a service-oriented system, businessfunctionality is typically exposed through services (for this discussion I llassume services are implemented in WCF) which means that a workflow is likelyto coordinate access to that functionality by calling those services.
Simply put, Workflow Services make it easy to expose aworkflow as a WCF service so that client applications can reach it, and make iteasy for workflows to call out to WCF services to coordinate access to businesslogic in a service-oriented system. The value Workflow Services bring to thetable is in the removal of overhead to set up communication between WCF andWorkflow to accomplish these two scenarios. Under the assumption you areemploying workflow in the middle-tier, Workflow Services become a staple itemin your application.
Workflow Service Features and Templates
Creating a Workflow Service involves leveraging several.NET Framework 3.5 features, including:
ReceiveActivity: A new Workflow activity thatimplements a WCF service operation.
SendActivity: A new Workflow activity forcalling WCF services from an executing workflow instance.
Context-aware bindings: New WCF bindingsspecifically for Workflow, which handle workflow instance management betweenclients and Workflow Services.
WorkflowServiceHost: A new ServiceHost type thatfacilitates communication between WCF services and the Workflow Runtime.
For a Workflow developer less familiar with WCF, it mightseem daunting to figure out how to create a service contract, select bindingsand configure endpoints, configure the ReceiveActivity and SendActivityaccordingly, and initialize the correct ServiceHost type. Fortunately, thereare two Visual Studio templates to simplify this process: Sequential WorkflowService Library and State Machine Workflow Service Library (see Figure 1).These templates are only shown if you select .NET Framework 3.5 from the AddNew Project list.
Figure 1: Workflow Service templates.
Each template creates a new class library project with asample workflow (sequential or state machine) that has been configured as aWorkflow Service as follows:
Each workflow starts with a ReceiveActivity(shown in Figures 2 and 3).
The ReceiveActivity is associated with a serviceoperation from a sample WCF service contract. When clients call the operationvia proxy, that particular ReceiveActivity is executed.
The class library includes an app.config filewith a sample configuration for the WorkflowService.
The binding used for the Workflow Serviceendpoint is WSHttpContextBinding, one of the context-aware bindings.
Essentially, the template generates a project with thenecessary assembly references, a sample Workflow Service, and the requiredconfiguration and set up so you can execute it. To test the service, the classlibrary is set up to use the two WCF test tools released with .NET Framework3.5, WCF Service Host (WcfSvcHost.exe) and WCF Test Client (WcfTestClient.exe).However, in this article I ll explain how to create your own host and client.
Note: Visit http://msdn.microsoft.com/en-us/library/bb552363.aspxand http://msdn.microsoft.com/en-us/library/bb552364.aspxfor more information about the test tools.
For sequential workflows, the ReceiveActivity is the firstactivity in the workflow (as shown in Figure 2). For state machine workflows,the ReceiveActivity is the first activity contained within an event-drivenactivity (as shown in Figure 3). Both sample workflows created by the templatesupport clients calling a WCF service operation to initialize the workflow, becausethe ReceiveActivity is configured to support workflow initialization.
Figure 2: Sequential WorkflowService template results.
Figure 3: State machine WorkflowService template results.
It is still possible to create Workflow Services withoutthe help of a Workflow Service template. You can add new sequential or statemachine workflows to a class library project and manually add theReceiveActivity, create the WCF service contract using dialogs provided, andadd the required WCF configuration settings for the Workflow Service endpoint.
ReceiveActivity
The most common use for Workflow Services is to expose aworkflow as a WCF service. The main benefit to the developer is that they nolonger have to manually initialize the Workflow Runtime or workflow instancefrom a WCF service operation. Instead, the Workflow Service directly exposes aWCF service operation via ReceiveActivity. This activity represents theimplementation of a WCF service operation.
Consider the Workflow Service shown in Figure 4. ThisWorkflow Service exposes three ReceiveActivity instances implementing three WCFservice operations: ReceiveOperation1, ReceiveOperation2, andReceiveOperation3. ReceiveOperation1 kicks off the workflow; ReceiveOperation2and ReceiveOperation3 can be called only after the workflow has started. Once aclient calls one of the latter two operations, the workflow is completed.
Figure 4: A Workflow Service withmultiple ReceiveActivity instances.
Each ReceiveActivity has a number of properties thatshould be initialized:
ServiceOperationInfo: Indicates the serviceoperation implemented by ReceiveActivity. This is set through the ChooseOperation dialog box.
CanCreateInstance: Indicates if the operationcan be called to initialize the workflow instance. If not, the workflow mustalready be initialized before ReceiveActivity can accept calls.
(ReturnValue): Associates the ReceiveActivityreturn value with a field or property of the workflow. Developers can set thisfield or property of the workflow to provide a return from the serviceoperation.
FaultMessage: Associates the ReceiveActivity faultmessage with a field or property of the workflow. Developers can set this valueto return a fault from the service operation. The client receives this as aFaultException.
[parameters]: These are dynamically generatedproperties based on the parameters to the service operation used to associatethe parameter with a field or property of the workflow so that developers haveaccess to these parameters throughout the ReceiveActivity sequence to implementservice operation logic.
Figure 5 illustrates the property values of the firstReceiveActivity instance.
Figure 5: ReceiveActivity propertiesfor ReceiveOperation1.
Workflow-first Services
The Choose Operation dialog box shown in Figure 6 is usedto set the ServiceOperationInfo property. From this dialog box you can eitherimport an existing service contract (Import) and select one of its operations,or define a contract for the Workflow Service (Add Contract) and an operation(Add Operation) for the specific ReceiveActivity instance being configured. A subsequentReceiveActivity instance can select the same contract and define additionaloperations. Workflow-first services imply that the WCF service contract doesnot exist until the Workflow Service is created. While designing the workflow,one or more service contracts can be defined with operations associated withReceiveActivity instances. Typically, you ll create a single service contract(as shown in Figure 5) for the Workflow Service, with as many operations asReceiveActivity instances. Figure 6 illustrates a service contract namedIWFService with three service operations defined for the Workflow Service usingthe workflow-first approach.
Figure 6: The Choose Operationdialog box with a workflow-first service contract.
Note: One drawbackto creating workflow-first services is lack of control over service contractproperties, such as the target namespace. I recommend importing a servicecontract created specifically for the Workflow Service to overcome thislimitation.
Workflow Service Configuration
Once the Workflow Service design is complete, and servicecontracts and operations are defined and associated with ReceiveActivityinstances, it s time to think about Workflow Service configuration. Because aWorkflow Service is implemented as a WCF service, each service contract musthave at least one service endpoint defined so clients can communicate with theservice. This is done with classic WCF configuration settings with theexception that it requires the use of a special context-aware binding. Thefollowing example illustrates a Workflow Service endpoint for the contractdefined in Figure 6 using WSHttpContextBinding:
binding="wsHttpContextBinding"
contract="IWFService">
There are three context-aware bindings introduced with.NET Framework 3.5: BasicHttpContextBinding, WSHttpContextBinding, andNetTcpContextBinding. Each binding includes a context binding element to enablecommunication between clients and a specific workflow instance.
Workflow Service Context
Context-aware bindings facilitate passing the workflowinstance identifier in message headers between client and service. When the firstReceiveActivity is called, the following header is included inthe response:
0cb1d8a4-4484-4d19-b33e-
a3f7bdb856c6
Because the client channel is configured to use the samecontext-aware binding, the client channel is responsible for caching thisinstanceId element for subsequent calls to the Workflow Service. The sameheader is sent for all calls from the same proxy instance to correlate theworkflow instance at the server.
Should the client channel be faulted, a new proxy can begenerated and initialized with the same instanceId. First, save the instanceIdby retrieving its value through the context manager:
IContextManager ctxManager =
m_proxy.InnerChannel.GetProperty;
IDictionary ctx = ctxManager.GetContext;
m_instanceId = ctx[ instanceId ];
If a new proxy is created and it is expected that the sameworkflow instance be used, create a new context with this value and assign itto the client channel:
m_proxy = new WinClient.localhost.WFServiceClient();
IContextManager ctxManager =
m_proxy.InnerChannel.GetProperty();
IDictionary ctx =
new Dictionary();
ctx.Add("instanceId", this.m_instanceId);
ctxManager.SetContext(ctx);
Note: If theWorkflow Service is configured to use Workflow Persistence Services, theworkflow instance state can be reloaded from the database. This makes it possibleto survive service channel faults and machine restarts.
ReceiveActivity Execution
The sequence contained within a ReceiveActivity isexecuted synchronously as part of the WCF service operation. Parameters passedto the operation can be used by the activities in the sequence, and before thesequence ends the activity s return value or FaultMessage should be set.Activities that follow a ReceiveActivity in the workflow are executedasynchronously to the client (because a response will have already been sentback as the ReceiveActivity terminates).
For the Workflow Service defined in Figure 4, theCodeActivity executes before sending a response to the client. The followingcode inside the CodeActivity sets the return value:
this.ReceiveOperation1Return = "ReceiveOperation1called";
this.ReceiveOperation1Fault = null;
If an exception occurs and the workflow should beterminated, a fault can be thrown by initializing the FaultMessage propertythrough its bound field:
this.ReceiveOperation1Fault = newFaultException("ReceiveOperation1 has faulted.");
Activities that follow a ReceiveActivity continue toexecute on the same thread as the ReceiveActivity although a response hasalready been sent to the client.
Note: Becauseactivities placed within a ReceiveActivity are executed synchronously to theclient, care should be taken that this sequence is not long running in order toavoid timeouts. Only those activities that contribute directly to the operationresponse need be part of the ReceiveActivity the rest can be executedasynchronously with the remainder of the workflow.
SendActivity
So far I ve focused on Workflow Services as exposing WCFservice endpoints to clients so they can invoke operations implemented byReceiveActivity instances. Another important feature of a Workflow Service isthe ability to easily call out to WCF service operations without the hassle ofprior techniques.
Using SendActivity, a Workflow Service can be configuredto call a particular WCF service contract by simply providing the servicecontract metadata, indicating the operation to call, binding parameters toworkflow fields or properties, and providing a configuration for the clientproxy. The proxy is automatically generated based on the information providedto the SendActivity, so it is not necessary to write code to call the serviceunless you are customizing the call to provide a dynamic address or specificsecurity settings.
Figure 7 illustrates the same Workflow Service from Figure4 (modified to add a call to a WCF service operation within eachReceiveActivity). Think of this as the Workflow Service coordinating downstreamservice calls according to a business process.
Figure 7: A Workflow Service callingout to downstream WCF service operations.
As with ReceiveActivity, developers can configure eachSendActivity by setting its properties. The key properties to initialize are:
ServiceOperationInfo: Indicates the serviceoperation to be invoked when the SendActivity instance is executed. This is setthrough the Choose Operation dialog box.
EndpointName: A child of the ChannelTokenproperty that specifies the WCF client configuration section to use for proxyinitialization. This can be shared by several SendActivity instances by usingthe same ChannelToken.
(ReturnValue): Associates the SendActivityreturn value with a field or property of the workflow. Developers can set thisfield or property of the workflow to share the return from the serviceoperation with the rest of the workflow.
[parameters]: These are dynamically generatedproperties based on the parameters to the service operation used to associatethe parameter with a field or property of the workflow. This removes the needfor code to initialize parameters passed to the service operation.
Figure 8 illustrates the property values of the firstSendActivity instance.
Figure 8: SendActivity propertiesfor Operation1.
To configure each SendActivity requires access to theservice contract and any custom data types relied upon by that contract. Theeasiest way to gain access to this is to either generate a proxy, or, if youown both projects, you can share a metadata assembly between the WorkflowService project and the service project(s). Once this metadata is available tothe project you can select the service contract and operation to associate witha SendActivity instance. After importing the service contract (see Figure 9)the same Choose Operation dialog box from Figure 6 is presented to select theoperation for the SendActivity being configured.
Figure 9: Selecting a servicecontract to be used for SendActivity instances.
SendActivity instances also require access to a configuration section specified in the EndpointName property. Thisconfiguration, which is usually created through proxy generation, must be partof the host process configuration file. To set the address of the service to becalled by a SendActivity instance, set the CustomAddress property.
WorkflowServiceHost
WorkflowServiceHost is an extension to ServiceHost (thetype responsible for initializing WCF communication channels at the service).WorkflowServiceHost adds functionality to facilitate communication between WCFand Workflow. When a request is received at a ReceiveActivity, theWorkflowServiceHost ensures the Workflow Runtime is initialized, initializes anew workflow instance if necessary (and if supported by the ReceiveActivity),then handles activating the workflow. For SendActivity instances, theWorkflowServiceHost constructs a client channel (or proxy) to call the specifiedservice operation.
To host a Workflow Service, construct theWorkflowServiceHost as follows:
WorkflowServiceHost hostWFService = new
WorkflowServiceHost(typeof(SequentialWFService.WFService));
hostWFService.Open();
If the workflow-first approach was used to generate theWCF contract, the WorkflowServiceHost is smart enough to reflect the workflowdefinition for this contract (because it is not statically defined).
To host Workflow Services in IIS or WAS, use theWorkflowServiceHostFactory in the .svc declaration (full name required):
<%@ ServiceHost Service="SequentialWFService.
WFService"Factory="System.ServiceModel.Activation.
WorkflowServiceHostFactory"%>
Next Up: Workflow Services and Security
In this article I introduced the Workflow Service,explained how to set up ReceiveActivity and SendActivity, and explained how thehosting model ties it all together. I have purposely left out security featuresfor Workflow Services as that topic requires an article of its own. So, staytuned to the next issue for the continuation of this discussion of WorkflowServices as I explain your options for securing ReceiveActivity andSendActivity.
Download the samplesfor this article from http://www.dasblonde.net/downloads/aspprooct08.zip.
Michele LerouxBustamante is Chief Architect of IDesign Inc., Microsoft Regional Directorfor San Diego, and Microsoft MVP for Connected Systems. At IDesign Micheleprovides training, mentoring, and high-end architecture consulting servicesfocusing on Web services, scalable and secure architecture design for .NET,federated security scenarios, Web services, interoperability, and globalizationarchitecture. She is a member of the International .NET Speakers Association(INETA), a frequent conference presenter, conference chair for SD West, and isfrequently published in several major technology journals. Michele also is onthe board of directors for IASA (International Association of SoftwareArchitects), and a Program Advisor to UCSD Extension. Her latest book is Learning WCF (O Reilly, 2007); visit her bookblog at http://www.thatindigogirl.com.Reach her at mailto:[email protected], orvisit http://www.idesign.net and her mainblog at http://www.dasblonde.net.
Read more about:
MicrosoftAbout the Author
You May Also Like