Building a workflow service using 4.0 gives a very neat set of capabilities from both WF and WCF. Similar to WCF we can fully define a workflow either in code or otherwise just using Xaml. Here I chose a fully code based approach. If you just want the source you can download it here.
We generally can take a workflow first approach or a contract first. To keep things simple, I have a very bare service contract as shown below.
[ServiceContract] interface IService1 { [OperationContract] void GetData(); }
I also hold on to the contract description. This is just convenience and to avoid some constants like service name etc.
ContractDescription description = ContractDescription.GetContract(typeof(IService1));
The idea here is to build the service bottom up from operation we need to perform. I can think of my workflow as composition of activities. The functionality of my service is quite simple here. All I do is write a message to the console. So the body of my operation will look something like this.
new WriteLine { TextWriter = Console.Out, Text ="Hello Workflow." },
Now I need to make this an operation. An operation has an associated message exchange pattern, commonly referred to as MEP. In my case it's a simple receive reply pattern. This means I have to compose my work in between a Receive and a SendReply. I am also going to tie this all up in Sequence as shown below.
Sequence sequence = new Sequence { Activities = { receive, new WriteLine { TextWriter = Console.Out, Text ="Hello Workflow." }, reply } };
The next thing is to lay out my Receive and Reply which will define the wire format of the messages.
Receive receive = new Receive { OperationName = description.Operations[0].Name, CanCreateInstance = true };
SendReply reply = new SendReply { Request = receive, Content = new SendParametersContent { } };
WorkflowService serviceDefinition = new WorkflowService { Body = sequence, Name = XName.Get(description.Name, description.Namespace) };
The next step is to give this definition to the workflow service host so that it can start the service. Here I self host the workflow as shown below.
WorkflowServiceHost host = new WorkflowServiceHost(serviceDefinition, new Uri("http://localhost:8080")); host.AddServiceEndpoint(serviceDefinition.Name, new BasicHttpBinding(), ""); host.Open();
Finally I can test the workflow using a simple proxy.
ChannelFactory<IService1> cf = new ChannelFactory<IService1>(new BasicHttpBinding(), "http://localhost:8080"); IService1 proxy = cf.CreateChannel(); proxy.GetData(); ((IChannel)proxy).Close();