Create a host project, ShoppingCartWorkflowServiceHost, as Listing 7-9 shows.. The first two are used to output trace information regarding the state transaction, and the third one is us
Trang 1233
9 Bindings for ShoppingCartItemWorkflow:StateCheckout are shown in
Figure 7-12
Figure 7-12 Bindings for ShoppingCartItemWorkflow:StateCheckout
Trang 2234
10 Bindings for ShoppingCartItemWorkFlow:Timeout are shown in Figure 7-13
Figure 7-13 Bindings for ShoppingCartItemWorkFlow:Timeout
11 Create a host project, ShoppingCartWorkflowServiceHost, as Listing 7-9 shows There are three callback delegates created in the Main() method
The first two are used to output trace information regarding the state transaction, and the third one is used to bind the persistence service for the workflow, so we can persist the workflow state
Listing 7-9 Create a Host Project ShoppingCartWorkflowServiceHost to Run the Workflow as a Service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.ServiceModel;
using System.ServiceModel.Description;
Trang 3235
namespace ShoppingCartWorkflowServiceHost
{
using ShoopingCartWorkflows;
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8000");
WorkflowServiceHost host =
new WorkflowServiceHost(typeof(ShoppingCartItemWorkflow), baseAddress);
host.Description.Behaviors
Find<WorkflowRuntimeBehavior>().WorkflowRuntime.WorkflowTerminated +=
delegate(object sender, WorkflowTerminatedEventArgs e) {
Console.WriteLine("WorkflowTerminated: " + e.Exception.Message);
};
host.Description.Behaviors
Find<WorkflowRuntimeBehavior>().WorkflowRuntime.WorkflowCompleted +=
delegate(object sender, WorkflowCompletedEventArgs e) {
Console.WriteLine("WorkflowCompleted.");
};
host.Description.Behaviors
Find<WorkflowRuntimeBehavior>().WorkflowRuntime.AddService(
new SqlWorkflowPersistenceService(
"Initial Catalog=WorkflowPersistenceStore;Data Source=localhost «
\\SQLEXPRESS;Integrated Security=SSPI;",
true,
TimeSpan.FromHours(1.0),
TimeSpan.FromSeconds(5.0)
));
host.Open();
Console.WriteLine(" Press <enter> key to exit ");
Console.ResetColor();
Console.ReadLine();
host.Close();
}
}
}
Trang 4236
12 In order to use HttpWebRequest and HttpWebResponse, add an App.config file to the project and insert the configuration for the host as shown in Listing 7-10 This host creates a Windows console application When the host application starts, it instantiates a WorkflowServiceHost instance Two parameters need to pass into the constructor to instantiate the host instance The first one is the type of the workflow, which in our case is ShoppingCartItemWorkflow, and the second one is the URI of the base address that the host is going to listen to for HTTP messages The host is going to look for the service contract from the workflow instance This is why we have to keep the service contract interface definition IShoppingCartService in the same assembly as the host and the implementation stays in a separate assembly ShoppingCartServiceLibrary; this assembly is also referenced by a client application
Listing 7-10 Configurations for the Service Host Program
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="ShoopingCartWorkflows.ShoppingCartItemWorkflow">
contract="ShoopingCartWorkflows.IShoppingCartService" />
</service>
</services>
<bindings>
<webHttpContext>
<binding name="myServiceBinding" contextMode="UriTemplate">
<uriTemplates>
<add name="ShoppingCartItems value="ShoppingCartItem/{instanceId}"></add> <add name="CreditCardPayments
value="CreditCardPayment/ShoppingCartItem/{instanceId}"></add>
</uriTemplates>
</binding>
</webHttpContext>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="MyServiceBehavior"><webHttp /></behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<bindingExtensions>
<add name="webHttpContext"
type="Microsoft.ServiceModel.Samples.WebHttpContextBindingCollectionElement, WebHttpContext, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null" />
</bindingExtensions>
</extensions>
Trang 5237
<diagnostics>
<messageLogging logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logEntireMessage="true"
logMessagesAtTransportLevel="true" />
</diagnostics>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging"
switchValue="Information, ActivityTracing">
<listeners>
<add name="ServiceModelMessageLoggingListener" />
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Verbose, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="messages.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
</add>
<add initializeData="tracelog.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
</add>
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
</configuration>
In order to test the results locally we need to set up a SQL Server database The WF workflow
state machine runtime needs SQL Server database support to persist runtime transaction data This
database can be set up using a SQL script The SQL scripting file used to create this database can
be found in C:\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN, as
Figure 7-14 shows Before running the script from SQL Server Management Studio, manually create a new database WorkflowPersistenceStore from SQL Server Management Studio or run CREATE TABLE
WorkflowPersistenceStore