Welcome to MSDN Blogs Sign in | Join | Help

Graham Elliott

Microsoft Services Architect

Syndication

News

My Photos
This is a Flickr badge showing public photos from Graham Elliott tagged with badge. Make your own badge here.

Integrating WCF and WF

One of the minor hurdles I came across when building out the first version of the über demo was how to call a Windows Communication Foundation (WCF) Service from a Windows Workflow Foundation workflow (WF).

The reason that this is more of a hurdle then you might expect is that Workflow Foundation does not have any "native" support for calling/invoking a WCF service... Well, not really, anyhow.

Basic(Http) Integration

WF does allow you to invoke a ASMX Web Service by using the InvokeWebService activity (see piccy below). This brings up the standard Visual Studio "Add Web Reference Interface", generates a client side proxy, and exposes a bunch of strongly bound properties for choosing the MethodName,  Parameters, ReturnValue etc.

Because you can call a standard ASMX web service, you can use the same method to invoke a WCF service that is exposed via a BasicHttpBinding endpoint. In the case of the AdentureWorks solution, I am calling the GetProducts service ...or more precisely, I am calling the following BasicHttpBinding endpoint:

<endpoint
   
name=
"basicHttp"
    
address=""
    
binding="basicHttpBinding"
   
contract="AdventureWorks.IProductsDB"/>

For this to work, I also had to configure the service to publish service metadata for retrieval using an HTTP/GET request.  

Slightly More Useful (but quick and dirty :-) Integration

So... Its pretty easy to call a WCF service from a workflow if you are happy to stick with a basic HTTP binding. But what if you want to use the full gamut of WCF features and bindings in your services?

If you take a look at the workflow in the AdventureWorks solution (piccy below) you will notice that I am using the InvokeWebService activity to call the GetProducts service and then using a code activity to to invoke the GetMostPopularProductsOfWeek service (using whatever binding I configure in the workflow host's app.config).

 

 The code for codeActivity1 looks like:

private void CodeActivity1_Execute(object sender, EventArgs e)
{
      //TODO: Add sensible robustness stuff here
     
this.TopProducts = proxy.GetMostPopularProductsOfWeek();
}

All I am doing is calling a method on the WCF "proxy" that I pass to the workflow via custom property that looks like:

private IProductsDB proxy;

public IProductsDB Proxy
{
      get { return proxy; }
     
set { proxy = value; }
}

This workflow property is populated by the workflow host, which in the case of the AdventrueWorks solution is the WPF Client, just before the workflow is kicked-off:

void GetProductList_OnClick(object sender, RoutedEventArgs e)
{
    if (SubCatID.Text != null)
    {
        // Construct workflow parameters
       
Dictionary<string, object> properties = new Dictionary<string, object>();
        properties.Add(
"SubCatID", Int32.Parse(SubCatID.Text));

        properties.Add(
"Proxy", pdb);     <---- HERE

        // Start the workflow
       
workflowInstance = workflowRuntime.CreateWorkflow(typeof(WorkflowLibrary1.Workflow1), properties);
        workflowInstance.Start();
    }
}

I have seen a bunch of other examples that actually construct the WCF channel stack in the code activity or (slightly better) as part of the workflow constructor. This causes a few problems (not mentioning the inefficiencies of it all)... the one that struck me was the loss of authentication context from the client. This is most evident when you switch to using a (WSHttpBinding or WSFederationHttpBinding based) CardSpace binding and you are presented with the CardSpace Digital Identities "card selector" everytime you hit the workflow - which is a little silly.

This very simple implementation is not without its own problems, namely it is really only suitable for very short running workflows (where you can pass an existing WCF channel across), doesn't provide a nice activity designer interface, etc. etc.

A More Elegant (and Complex) Approach

For a more elegant and complex approach to this problem, check out the Workflow Adapter / Connector Pair example on The Code Project  by Roman Kiss. This is a great example of a framework for abstracting the connection between workflows, remoting and services.

Published Monday, January 08, 2007 1:21 PM by grahame

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
required 
(required) 
Page view tracker