On the WF ReceiveActivity and WCF bindings

Posted Wednesday, March 26, 2008 6:46 PM by Maurice

The new ReceiveActivity and SendActivity that marry Windows Workflow Foundation (WF) and Windows Communication Foundation (WCF) are really cool Smile. 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 Sad. 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 Sad. 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

Filed under: , , , , , ,

Leave a Comment

(required) 
(required) 
(optional)
(required)