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="https://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:d="clr-namespace:DeclarativeSequentialServiceLibrary1;assembly=DeclarativeSequentialServiceLibrary1" xmlns:p="https://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:x="https://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.
Comments
- Anonymous
July 30, 2009
For me Workflow services is a mixed bag, there are few things I’m not willing to trade off : -Contract First: it’s just awkward, I want be able to declare the service contract and then pick the operation to implement in the receive shape. -I want to be able to group workflows as service operations instead of independent services, for example in the video you have HRService, what if I want to have a single workflow for process the application , other dedicated to check the application status, other for vacation request, other for raise request, other for complains and so on, all related to HRServices however I can’t host all of them under http://localhost:8080/HRservices and “see” them as operations( ProcessApplication, CheckApplicationStatus, VacationRequest, RaiseRequest, Complains ) I’ll have to host each of them under different addresses and treat them as separate services, in other words I’ll end up having for example: http://localhost:8080/ProcessApplication http://localhost:8081/CheckApplicationStatus http://localhost:8082/VacationRequest http://localhost:8083/RaiseRequest http://localhost:8083/Complains To accomplish the desire functionality (single service many operation) today we have to use parallel/ pick shapes which again doesn’t feel natural. Just my thoughts, other than that; thanks and keep up the good work