FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
SOA Web Services Blog: Service-Enabled Workflows with WF and WCF
XML & Web Services
<![CDATA[[

Web Services and Smart Data.

by John Dorsey
THE SOFTWARE SIMPLIST

Web Services Wisdom.

by Udi Dahan
June 19, 2007

Service-Enabled Workflows with WF and WCF

I’ve looked over the example Guy put up in his blog on how to interact with external services from a workflow, and tried it out using asynchronous APIs with WCF. This is done quite simply by having our service accept an object as a parameter that it can call methods on (which has availability issues, but whatever). The object that we pass in is quite simply a reference to our own service. Anyway, I haven’t been able to get the SendActivity in WF to work with it. Bummer. I guess I’m "stuck" doing things the "old fashioned" way. Check out the full ESB API as well.

By having messages dealing with workflow contain the ID of the specific instance they refer to, we can do simple message to workflow mapping. When a message handler receives a message containing a workflow ID, it just goes to the workflow store and retrieves the object by its ID. Finally, it calls the Handle method on that object, and I’m done. Workflow classes are just state machines whose triggers are the arrival of a message.

Here’s some example code so you can see how simple it really is:

public class WorkflowMessageHandler : IMessageHandler<Stage1Msg>
{
	public void Handle(Stage1Msg msg)
	{
		using (IDBScope scope = this.DbServices.GetScope(TransactionOption.On))
		{
			IWorkflow wf = this.DbServices.Get(msg.WorkFlowID);
			wf.Handle(msg);

scope.Complete();
}
}
}

You can see how easy it would be to take this and make it generic. Just define an IWorkflowMessage that inherits from IMessage and has a single property - WorkFlowID. Then we could have a BaseWorkflowMessageHandler<T> which would inherit from IMessageHandler<T> where T : IWorkflowMessage.

After that, it would be enough to have a class inherit from the base for a specific message and you'd be done, just like this:

public class Stage1Message : IWorkflowMessage { // WorkFlowID and other data };

public class WorkflowMessageHandler : BaseWorkflowMessageHandler<Stage1Msg> {}

I could even automate the creation of these message handlers given the set of messages that correspond to a workflow. I could then create all sorts of sexy designers on top of that.

But, seeing as there's so little extra code to get long-running workflows to work with "asynchronous services", I don't think I'll bother. I mean, why do I even need a "SendActivity"? It's just a simple little call:

this.Bus.Send(msg);

It appears that clean designs don't leave much to be draggy-dropped. Oh well. Your mileage may vary.

Posted by Udi Dahan at 06:20 PM  Permalink




 
INFO-LINK