Sharepoint 2010 : Creating a Pluggable Workflow Service (part 4) - Using the ExternalDataExchange Attribute, Deriving from SPWorkflowExternalDataExchangeService

11/4/2013 2:57:54 AM

2. Creating a Pluggable Workflow Service

Having set up the communications mechanism between the calculation engine and SharePoint, our next step is to create a pluggable workflow service that can be hooked up to our SharePoint service to broker requests between the WCF service and SharePoint’s workflow engine. Before we get into the code, I’ll show you how pluggable workflow services work.

As mentioned, pluggable workflow services can be created by inheriting from SPWorkflowExternalDataExchangeService. External data exchange services, also known as local services, are a key component of the WF framework. Without local services, a workflow runtime has no means of communicating with the external environment, and in fact SharePoint defines two local services that allow the workflow runtime to communicate with the SharePoint platform itself: SPWinOEWSSService and SPWinOETaskService. For the most part, the SharePoint workflow activities that are available out of the box make use of these services for communication.

Generally speaking, WF can be configured using a configuration file. The configuration can specify which services should be available to the runtime and how certain functions are performed. Since allowing changes to the configuration at this level could cause major support issues, Microsoft chose to disallow workflow configuration in SharePoint via the normal channels. In previous versions of SharePoint, this meant that no additional local services could be added. However, with SharePoint 2010, an additional configuration handler has been implemented that allows objects of type SPWorkflowExternalDataExchangeService to be added to the workflow runtime.

External data exchange services are created in a similar fashion to WCF services. An interface is defined that determines the methods and events that should be available to the workflow runtime. Once the interface is completed, a local service class based on SPWorkflowExternalDataExchangeService and implementing the interface is created. Finally, the local service class is added to the configuration for the workflow runtime.

Using the ExternalDataExchange Attribute

Now that you understand how pluggable services work, let’s move on to our implementation.

We first add an interface for our service. Add a new interface file to the WorkflowDemonstration solution named IExternalCalculationService.cs. Add the following code:

using System;
using System.Workflow.Activities;

namespace WorkflowDemonstration
public interface IExternalCalculationService
event EventHandler<CalculationResultArgs> CalculationComplete;
void SubmitCalculation(string product);

public class CalculationResultArgs : ExternalDataEventArgs
public CalculationResultArgs(Guid id) : base(id) { }
public string Result;


Creating workflow services requires references to System.Workflow.Activities and System.Workflow.Runtime.

Notice a few things about this code sample. Firstly, the ExternalDataExchange attribute is used to let the workflow runtime know that the interface should be accessible to workflow activities. We’ll build up a workflow later to see this in action. Secondly, any events that are raised must be derived from the ExternalDataEventArgs class and must be serializable. The ExternalDataEventArgs class defines the base parameters that are required to route the event to the correct workflow instance. Because the workflow will most likely be running in a different application domain, events must be serializable in order to be passed to the runtime.

Deriving from SPWorkflowExternalDataExchangeService

With the interface in place, we can move on to creating an implementation of the service.

Add a new class named CalculationWorkflowService and then add the following code to the CalculationWorkflowService.cs file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.Activities;
using System.ServiceModel.Activation;
using Microsoft.SharePoint.Workflow;
using System.Workflow.Runtime;

namespace WorkflowDemonstration
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirements-
class CalculationWorkflowService: SPWorkflowExternalDataExchangeService, IExternal-
public event EventHandler<CalculationResultArgs> CalculationComplete;

public void SubmitCalculation(string product)
//Call WCF Service

public override void CallEventHandler(Type eventType,
string eventName,
object[] eventData,
SPWorkflow workflow,
string identity,
IPendingWork workHandler,
object workItem)
//raise event
public override void CreateSubscription(MessageEventSubscription subscription)
throw new NotImplementedException();

public override void DeleteSubscription(Guid subscriptionId)
throw new NotImplementedException();

The main thing worth mentioning with regard to this code sample is the override of CallEventHandler. CallEventHandler is defined on the SPWorkflowExternalDataExchangeService base class and is used to relay events back to the workflow runtime with sufficient information to recover the relevant SharePoint context. CreateSubscription and DeleteSubscription are marked as MustInherit in the base class but are not required by our service and therefore have default implementations.

  •  PowerShell for SharePoint 2013 : Word Automation Services - Disable Word 97–2003 Document Scanning , Disable Embedded Fonts in Conversions
  •  PowerShell for SharePoint 2013 : Word Automation Services - Modify Job Monitoring, Modify Conversion Timeouts
  •  PowerShell for SharePoint 2013 : Word Automation Services - Configure Supported Document Formats for Conversion, Modify Database Information
  •  PowerShell for SharePoint 2013 : Word Automation Services - Configure the Conversion Processes, Configure Conversion Throughput
  •  ASP.NET 4 : Error Handling, Logging, and Tracing - Throwing Your Own Exceptions
  •  ASP.NET 4 : Error Handling, Logging, and Tracing - Handling Exceptions
  •  ASP.NET 4 : Error Handling, Logging, and Tracing - Exception Handling
  •  ASP.NET 4 : Error Handling, Logging, and Tracing - Common Errors
  •  Sharepoint 2010 : Designing a Workflow Using Visio 2010 (part 3) - Using Visio Services to Visualize Workflow State
  •  Sharepoint 2010 : Designing a Workflow Using Visio 2010 (part 2) - Implementing a Visio Workflow Using SharePoint Designer
    Top 10
    Review : Sigma 24mm f/1.4 DG HSM Art
    Review : Canon EF11-24mm f/4L USM
    Review : Creative Sound Blaster Roar 2
    Review : Philips Fidelio M2L
    Review : Alienware 17 - Dell's Alienware laptops
    Review Smartwatch : Wellograph
    Review : Xiaomi Redmi 2
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8