On the WF ReceiveActivity and WCF bindings

The new ReceiveActivity and SendActivity that marry Windows Workflow Foundation (WF) and Windows Communication Foundation (WCF) are really cool [:)]. Getting started is easy because a new Sequential Workflow Service Library, found under WCF instead of Workflow in VS2008, uses nice defaults for everything. But sooner or later you need to change these defaults and you need to know what can be done and what can’t.

When you want to use the new ReceiveActivity in a workflow you need to use a compatible WCF binding. The reason for this requirement is that the conversation context, see this blog post, is part of the message and needs to be retrieved and returned. The following code returns a list of all WCF binding and how they are composed:

Sub Main()

Dim assemblies As New List(Of Assembly)()

‘ .NET 3.0

assemblies.Add(GetType(ServiceHost).Assembly)

‘ .NET 3.5

assemblies.Add(GetType(WorkflowServiceHost).Assembly)

assemblies.Add(GetType(WebServiceHost).Assembly)

 

Dim query = From assembly In assemblies _

From type In assembly.GetTypes() _

Where type.IsSubclassOf(GetType(Binding)) _

AndAlso Not type.IsAbstract _

AndAlso type.IsPublic _

Order By type.Name _

Select type

 

PrintBinding(query.ToList)

 

Console.ReadLine()

End Sub

 

Private Sub PrintBinding(ByVal types As List(Of Type))

For Each type In types

Console.WriteLine(type.FullName)

Try

Dim binding As Binding = _

CType(Activator.CreateInstance(type), Binding)

Dim elements = binding.CreateBindingElements

For Each element In elements

Console.WriteLine(vbTab + element.GetType().FullName)

Next

Catch ex As Exception

Console.WriteLine(ex.Message)

End Try

Console.WriteLine()

Next

End Sub

 

The classes responsible for inserting and removing these conversation tokens are ContextRequestChannel and ContextReplyChannel and they are instantiated by the ContextBindingElement. So seems we are restricted to using BasicHttpContextBinding, NetTcpContextBinding or WSHttpContextBinding.

So it seems we cannot use NetMsmqBinding which is a shame because one way reliable messaging is the perfect fit for workflow as far as I am concerned. Well not quite so fast because we still have the CustomBinding where we can configure the stack just the way we want right?

Yeah we do but there is a problem [:(]. It turns out the ContextBinding requires a channel with an IReplyChannel interface and the NetMsmqBinding actually implement an IInputChannel or an IOutputChannel. Which one actually depends if you are the client or the service.

And thinking about how WF/WCF conversations works this restriction makes sense. After all a ReceiveActivity is called without a context in order to create a new workflow, assuming the CanCreateInstance property equals true, and returns the workflow instanceId in the context as part of the response. This design kind of rules out one-way messages and thereby NetMsmqBinding.

Now this sucks big time if you ask me [:(]. I would much rather have seen that you could specify the instanceId of the workflow to be created, just as you can with the WorkflowRuntime.CreateWorkflow() where a number of the overloads let you specify the workflows instanceId. I suppose it is possible to create a different context binding but that would be quite some work and, I assume, duplicate a lot of code already written my Microsoft. So let’s hope they see the light and add MSMQ/ReceiveActivity intergration.

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

2 thoughts on “On the WF ReceiveActivity and WCF bindings

  1. Actually, you CAN use a NetMsmqBinding with WF. I’ve done it. Just mark the contract as OneWay and set the initial RecieveActivity to implement it.

    Unfortunately, you still can’t use a NetMsmqBinding on the initial receive activity if you’re hosting the WCF service in IIS. Some combination of WCF, MSMQ, WF, and WAS (activation services) doesn’t let a workflow be activated by receipt of an MSMQ message.

  2. What where you using as the host application when using the NetMsmqBinding?

    Normally with the WCF/WF bridge you need to be using one of the context bindings. These not only make sure the workflow instanceId is routed but also add the behavior that creates and manages the WF runtime. So no context binding means no correlation and no runtime.

    With any luck using MSMQ with WF should become a supported scenario in the future though. Stay tuned for more after the PDC.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>