Recently I saw a message on the WF4 Forum where someone was asking for help learning how to consume a WCF service from a Workflow.

In this post I’m going to walk through how you can consume a WCF service from a Workflow where both the service and the workflow live in the same web site.  This should be simple, but unfortunately it is not as simple as it should be.

Get Microsoft Silverlight

Create an ASP.NET Web Application

  1. Start Visual Studio 2010 and Create a new ASP.NET Web Application
  2. Add a new WCF Service to the project
  3. Add a new Activity to the project

Add a Service Reference To The WCF Service

  1. Right click on the project and select Add Service Reference
  2. Click on the Discover button to locate the service
  3. Add the reference

Now What…

A standard WCF service reference was created but the generated client class is not an activity.  You could create a CodeActivity (or better yet an AsyncCodeActivity) to use the generated class but really that is not the best solution.

The Problem

The problem is that there are 2 implementations of Add Service Reference.  The original one (let’s call it ASR-Code) which generates the typical code based client classes and then another one we call ASR-XAML which generates a XAML based WF client proxy.

How do we know which one to invoke when you right click and say Add Service Reference?  We know by looking at the project type.  If you start your project as an Activity Library or a WCF Workflow Service application then you get ASR-XAML, everything else gets ASR-Code which is why we got a code based proxy when we really wanted a XAML based proxy.

The Workaround

The workaround is to add a new Activity Library project to your solution and then add the service reference from there.  But… once again it is not as easy as it should be. 

Add a new Activity Library project

  1. Right click on the solution and select Add new project
  2. Create a new project of type Activity Library

Add a Service Reference To The WCF Service

  1. Right click on the project and select Add Service Reference
  2. Click on the Discover button to locate the service
  3. Add the reference
  4. A dialog will appear reminding you to build the project and you will have a new XAML based activity in the toolbox to consume the service

Use the New Activity in your Web Application

  1. Right click on the Web App and add a project reference to the Activity Library

Doh! Just when we thought he had this problem solved…

The Workaround For The Workaround

In this case there is a loophole we can exploit and is has to do with the order of operations.  Try this.

  1. Delete the activity library project
  2. Add another activity library project
  3. From your Web App add a project reference to the activity library
  4. Now add a service reference from the activity library to the service in your web app
  5. Build the solution

Now your XAML activity can be used from the web app

Really?  What alternatives are there?

If you don’t want to use these workarounds there are some options

Option – Bypass the service and invoke the business logic from a CodeActivity

If your business logic lives in the same web app, you might be able to invoke the business logic directly without sending a message through WCF.  If you can do this it will result in better performance as well as avoid the problem all together.

Option – Use an AsyncCodeActivity to invoke your service logic

If you do need to send a message, you can use the WCF generated code proxy async interface (you have to generate w/async support).  I highly recommend async but you can also use a CodeActivity if you don’t want to do async but this will hurt your performance.

Option – put your activities into a separate WCF Workflow Service Web application

This will keep the boundaries clear and you can invoke your services in their own application.  The downside is that you now have 2 web applications to manage.

Is this going to get better?

Yes, we have an open bug on this and are considering options for making this better in the future.  One option might be to simply let you choose if you want the XAML reference to be generated when you create a service reference.  Don’t know how long it will be before this gets better but it probably will not be fixed until the next release of Visual Studio.