ShoppingCart WCF Service Library using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; using System.ServiceModel; nam
Trang 1213
Listing 7-1 ShoppingCart WCF Service Library
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace CloudWorkflowServiceLibrary
{
[ServiceContract]
public interface IShoppingCartService
{
[OperationContract(IsOneWay = true)]
void Ping();
}
[DataContract]
public class ShoppingCartItem
{
[DataMember]
public string SKU;
[DataMember]
public string ProductName;
[DataMember]
public DateTime AddTime;
[DataMember]
public int ItemCount;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Diagnostics;
namespace CloudWorkflowServiceLibrary
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ShoppingCartService : IShoppingCartService
{
public void Ping()
{
string message =
Trang 2214
string.Format(" -{0}:Ping, {1}", DateTime.Now.ToString(), this.ToString()); Trace.WriteLine(message);
Console.WriteLine(message);
}
#endregion
}
}
2 Create a console application project to host the WCF service that we have
just created Name the project ShoppingCartServiceHost Add a reference to System.ServiceModel.dll and Microsoft.ServiceBus.dll (This assembly can
be found in C:\Program Files\Microsoft NET Services SDK\Assemblies.) Insert a few lines of code into the Main() method body as Listing 7-2 shows
The setting options NetEventRelayBinding, TransportClientEndpointBehavior, and UserNamePassword credentials to authenticate to the NET Service Bus are needed here because the workflow will be calling the service There is not much difference from the Main() methods we have seen in previous chapters:
the security authentication type can be switched from the user name and password to other types such as CardSpace or X.509 certificate
Listing 7-2 Local WCF Service Host ShoppingCartServiceHost
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace ShoppingCartServiceHost
{
using Microsoft.ServiceBus;
using CloudWorkflowServiceLibrary;
class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(ShoppingCartService));
ServiceEndpoint endpoint =
host.AddServiceEndpoint("CloudWorkflowServiceLibrary.IShoppingCartService", new NetEventRelayBinding(),
"sb://servicebus.windows.net/services/SoftnetSolutions 113/ShoppingCart"); TransportClientEndpointBehavior transportEndpointBehavior =
new TransportClientEndpointBehavior();
transportEndpointBehavior.CredentialType =
TransportClientCredentialType.UserNamePassword;
transportEndpointBehavior.Credentials.UserName.UserName = "[your user name]";
Trang 3215
transportEndpointBehavior.Credentials.UserName.Password =
"[your solution password]";
endpoint.Behaviors.Add(transportEndpointBehavior);
try
{
host.Open();
Console.WriteLine("Host is running");
Console.ReadLine();
host.Close();
}
catch (Exception ex)
{
Console.WriteLine(
string.Format(" -ShoppingCartServiceHost:Main, exception caught {0}",
ex.Message));
}
}
}
}
3 Create a cloud sequential workflow project from Visual Studio as shown in
Figure 7-2 and call it CloudSequentialShoppingCartWorkflow
Figure 7-2 Create a cloud sequential workflow project
Trang 4216
4 Drag a CloudXPathUpdate from the toolbox and drop it on the workflow design surface, as Figure 7-3 shows Call it CreateShoppingCartServiceBusMessage
Figure 7-3 Add a CloudXPathUpdate activity to the design surface
5 Enter the binding information into the Properties dialog box as shown following At runtime, the input information (InNewValue) will be populated into the <input></input> node using the XPath expression as the search string
InNewValue = "Hello from ShoppingCart Workflow"
InXml = "<Ping><input></input></Ping>"
InXPathExpresssion ="/Ping/input"
6 Add a CloudServiceBusSend activity below the CloudXPathUpdate activity on the workflow design surface and call it SendShoppingCartInfo
7 Make sure the binding information is as following
Action = "urn:IShoppingCartService/Ping"
Body Name = "CreateShoppingCartServiceBusMessage"
Body Path = "OutXml"
ConnectionMode = "Multicast"
URL = "sb://servicebus.windows.net/services/SoftnetSolutions 113/ShoppingCart"
8 Now we have all the necessary information for the workflow design and are ready to deploy to the Microsoft data center Right-click on the workflow design surface to bring up the Workflow Cloud Deployment dialog box, and enter your credential information
9 Go to https://workflow.ex.azure.microsoft.com/WorkflowManagement.asp and verify that the workflow has been successfully deployed to Microsoft as shown in Figure 7-4
Trang 5217
Figure 7-4 Verifying that the service has been deployed using Azure Portal
Before we finish our development let’s shift the topic a little bit to discuss the limitations of using
cloud state machine workflows with the current NET Workflow Service In order to understand what is going to happen at runtime if we deploy a state machine workflow to the cloud, let us deploy a workflow with state machine type or with a custom-defined activity to the cloud For example, let's switch back to our project and define a custom workflow activity as Listing 7-3 and Listing 7-4 show This is a very
simple custom activity used to send an e-mail notification when a WCF service call is received If we host this workflow activity in a worker role like in Listing 7-2, we get a security exception, saying that the
worker role failed to start because an assembly call cannot be loaded from a partially trusted assembly,
as Figure 7-5 shows Actually, the assembly related to the exception is System.Workflow.Activities as
highlighted in Listing 7-3; we have to reference this assembly from the project, but it has not been