Windows Workflow in .NET 4 and Web Services
Today I published 10-4 episode 29: Workflow Web Services on our Channel 9 10-4 Show about Workflow Services in .NET 4 beta 1.
People have asked me why they would want to implement a web service with a workflow rather than with code using WCF. It is a valid question. Over the next few blog posts I’ll describe some of the reasons why I find workflows a very interesting solution for implementing web services.
Workflows are a simple way to implement web services
Remember the ABC’s of web services with WCF? Every service has an Address, Binding and Contract right? Well it turns out that this isn’t as simple as it sounds. With Workflow services I don’t have to bother so much with the ABC’s. Instead I can focus on a declarative model where I simply create a variable of some type that I want to receive and put it into a receive shape.
Here is a screenshot of a Declarative Sequential Workflow Service in Visual Studio 2010 Beta 1.
This picture is a visualization of XAML that describes a contract. And what is the contract? You can see it from the WCF Test Client
Ok – so the name is a bit ugly but it is just a property of the receive activity easy to change. I have a contract with a method named GetData. And what does the GetData method use as an argument? The value is an Int32, of course because this is a web service message the value might not be included so the WCF Test Client now allows me to use a Nullable<Int32>
And the workflow definition is just a XAMLX file that I can drop on the web server (along with any assemblies it uses) and have a complete working service.
1: <Service xmlns="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:d="clr-namespace:DeclarativeSequentialServiceLibrary1;assembly=DeclarativeSequentialServiceLibrary1" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
2: <WorkflowServiceImplementation ConfigurationName="Service1" Name="Service1">
3: <p:Sequence DisplayName="Sequential Service" sad:XamlDebuggerXmlReader.FileName="c:\scratch\DeclarativeSequentialServiceLibrary1\DeclarativeSequentialServiceLibrary1\Service1.xamlx">
4: <p:Sequence.Variables>
5: <p:Variable x:TypeArguments="CorrelationHandle" Name="handle" />
6: <p:Variable x:TypeArguments="x:Int32" Name="data" />
7: </p:Sequence.Variables>
8: <Receive x:Name="__ReferenceID0" CanCreateInstance="True" DisplayName="ReceiveRequest" OperationName="GetData" ServiceContractName="Contract1" ValueType="x:Int32">
9: <Receive.AdditionalCorrelations>
10: <p:InArgument x:TypeArguments="CorrelationHandle" x:Key="ChannelBasedCorrelation">[handle]</p:InArgument>
11: </Receive.AdditionalCorrelations>
12: <Receive.KnownTypes>
13: <x:Type Type="x:Int32" />
14: </Receive.KnownTypes>
15: <p:OutArgument x:TypeArguments="x:Int32">[data]</p:OutArgument>
16: </Receive>
17: <d:TraceActivity Message="[String.Format("Received data {0}", data)]" />
18: <SendReply Request="{x:Reference __ReferenceID0}" DisplayName="SendResponse" ValueType="x:String">
19: <p:InArgument x:TypeArguments="x:String">[data.ToString()]</p:InArgument>
20: </SendReply>
21: </p:Sequence>
22: </WorkflowServiceImplementation>
23: </Service>
This is a pretty cool way to declare a service. If I want to get a little more complex, I can create a type that is received with multiple properties and such. This is exactly what we are doing in the Introduction to Workflow Services lab from the Visual Studio 2010 Training Kit.