付録 A: Order アプリケーションの開発

この付録では、開発者が Contoso Order サービスを構築するための詳細な手順を示します。この付録の目的は、Visual Studio 2010 と .NET Framework 4 を使用して、Windows Communication Foundation (WCF) や Windows Workflow Foundation (WF) サービスなどのアプリケーションを開発する手順に、開発者に慣れていただくことです。このチュートリアルの主な部分では、システム管理者やアプリケーション所有者が、Microsoft AppFabric 1.1 for Windows Server を使用して、WCF や WF サービスを含むアプリケーションの展開、監視、およびトラブルシューティングを行う方法を示します。

この Contoso Order サービスは、以下の 4 つのアプリケーションで構成されています。

  • Order Process サービス: Web サービス インターフェイスを通じて、既存の注文処理アプリケーションの呼び出しをシミュレートする WCF サービス。

  • Shipping サービス: API を通じて、既存の出荷アプリケーションの呼び出しをシミュレートする WCF サービス。

  • Order Workflow サービス: 注文の受け付け、注文の処理、および注文の出荷など、注文処理を管理する WF ワークフロー サービス。

  • Order クライアント: Order サービスのフロント エンドとして機能する Windows フォーム アプリケーション。

ヒント

この付録を使用するにあたって Windows Server AppFabric をインストールする必要はありません。ただし、正しいファイル構造を作成して適切にビルドできるように、「Microsoft AppFabric 1.1 for Windows Server インターフェイスの使用に関するチュートリアル」のファイルをあらかじめインストールする必要があります。「Microsoft AppFabric 1.1 for Windows Server インターフェイスの使用に関するチュートリアル」を最後まで実行する必要はありませんが、ファイルだけはインストールしてください。「Microsoft AppFabric 1.1 for Windows Server インターフェイスの使用に関するチュートリアル」のインストール方法については、「レッスン 1: はじめに」を参照してください。C:\DublinTutorial\OrderServiceSolution\Completed フォルダーには、完成したソリューションのコピーが保存されています。

手順

アプリケーションを作成するには、以下の手順を実行します。

  1. Order Processing WCF サービスの開発

  2. Shipping WCF サービスの開発

  3. Order Workflow WF サービスの開発

  4. Order Processing WCF サービスの完成

  5. Shipping WCF サービスの完成

  6. Order クライアント アプリケーションの開発

  7. Order サービスのパッケージ

Order Processing WCF サービスの開発

Order Processing アプリケーションは、Contoso が購入したアプリケーションです。このアプリケーションには、他のアプリケーションから通信できる Web サービスが付属しています。Contoso 開発者として、Order Processing アプリケーションを操作する OrderProcessingService という名前の WCF サービスを開発する必要があります。

OrderProcessingService 用の Visual Studio ソリューションおよび WCF サービス アプリケーションを作成するには

  1. [スタート] ボタンをクリックし、[すべてのプログラム]、[Microsoft Visual Studio 2010] の順にポイントして、[Microsoft Visual Studio 2010] をクリックします。

  2. [ファイル] メニューの [新規作成] をクリックし、[新しいプロジェクト] をクリックします。

  3. [新しいプロジェクト] ダイアログ ボックスで、以下の値を選択または入力し、[OK] をクリックします。

    プロパティ

    プロジェクトの種類

    Visual C#/Web

    テンプレート

    WCF サービス アプリケーション

    プロジェクト名

    OrderProcessingService

    場所

    C:\DublinTutorial\OrderServiceSolution

    ソリューション名

    OrderService

    ソリューションのディレクトリを作成する

    (オン)

  4. ソリューション エクスプローラーで、OrderProcessingService を展開し、IService1.cs を右クリックして、[削除] をクリックします。

  5. ファイルを完全に削除することを確認するメッセージが表示されたら、[OK] をクリックします。

  6. ソリューション エクスプローラーで、OrderProcessingService を展開し、Service1.svc を右クリックして、[削除] をクリックします。

  7. ファイルを完全に削除することを確認するメッセージが表示されたら、[OK] をクリックします。

WCF サービスを作成する際の最初の作業は、コントラクトを定義することです。コントラクトは、サービスでサポートされる操作を指定します。操作は、Web サービス メソッドと考えることができます。インターフェイスの各メソッドは、特定のサービス操作に対応します。OrderProcessingService では、ProcessOrder と CancelOrderProcess の 2 つのメソッドを定義します。

Order Processing サービスのサービス コントラクトおよびデータ コントラクトを定義するには

  1. ソリューション エクスプローラーで、OrderProcessService を右クリックし、[追加] をポイントして、[新しい項目] をクリックします。

  2. [新しい項目の追加 - OrderProcessService] ダイアログ ボックスで、以下の値を選択または入力し、[追加] をクリックします。

    プロパティ

    カテゴリ

    Visual C#/Web

    テンプレート

    WCF サービス

    ファイル名

    OrderProcessing.svc

    ソリューションに、IOrderProcessing.cs と OrderProcessing.svc の 2 つのファイルが追加されます。

  3. ソリューション エクスプローラーで、IOrderProcessing.cs をダブルクリックして開きます。

  4. OrderProcessingService 名前空間を右クリックし、[リファクター] をクリックし、[名前の変更] をクリックして、[名前の変更] ダイアログ ボックスを開きます。

  5. [新しい名前] ボックスに、「Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService」と入力し、[OK] をクリックします。

  6. [適用] をクリックし、[はい] をクリックします。

  7. OrderProcessing.svc のソース コードを、次のように変更します。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService
    {
        [ServiceContract]
        public interface IOrderProcessing
        {
            [OperationContract]
            string ProcessOrder(PurchaseOrder po);
    
            [OperationContract]
            string CancelOrderProcess(string orderID);
        }
    
        [DataContract]
        public class PurchaseOrder
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string FirstName;
            [DataMember]
            public string LastName;
            [DataMember]
            public string EmailAddress;
            [DataMember]
            public string TelephoneNumber;
            [DataMember]
            public string AddressLine1;
            [DataMember]
            public string AddressLine2;
            [DataMember]
            public string City;
            [DataMember]
            public string State;
            [DataMember]
            public string ZipCode;
            [DataMember]
            public string Description;
            [DataMember]
            public int Quantity;
            [DataMember]
            public string UnitPrice;
        }
    }
    

    このファイルで、データ コントラクトとサービス コントラクトを定義します。クライアントは、このサービスを呼び出して、注文を処理したり、注文の処理をキャンセルしたりすることができます。

インターフェイスを使用して定義されるコントラクトを作成したら、次の手順はインターフェイスの実装です。この手順では、ユーザー定義の IOrderProcessing インターフェイスを実装する OrderProcessService という名前のクラスを作成します。

Order Process サービス コントラクトを実装するには

  1. ソリューション エクスプローラーで、IOrderProcessing.cs をダブルクリックして開きます。

  2. ソース コードを、次のように変更します。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Threading;
    using System.IO;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService
    {
        class WorkItem
        {
            private Thread workThread;
            private object workItemLock;
            private bool completeFlag;
    
            public Thread WorkThread { get { return workThread; } set { workThread = value; } }
            public object WorkItemLock { get { return workItemLock; } }
            public bool CompleteFlag { get { return completeFlag; } }
    
            public WorkItem(Thread WorkThread)
            {
                workThread = WorkThread;
                workItemLock = new object();
                completeFlag = false;
            }
    
            public void Complete()
            {
                completeFlag = true;
            }
        }
    
        public class OrderProcessing : IOrderProcessing
        {
            private static Dictionary<String, WorkItem> WorkItemMap = new Dictionary<String, WorkItem>();
    
            public string ProcessOrder(PurchaseOrder po)
            {
                //run the code from a different thread to simulate asynchronized call
                ThreadPool.QueueUserWorkItem(SendProcessResult, po);
                return ("The request for processing order[" + po.POID + "] has been received.");
            }
    
            private void SendProcessResult(object state)
            {
                PurchaseOrder po = (PurchaseOrder)state;
    
                WorkItem workItem = new WorkItem(Thread.CurrentThread);
                WorkItemMap.Add(po.POID, workItem);
    
                //Simulating the order processing process
                Thread.Sleep(120000);
    
                //The following code will be uncommented later in the process
                //OrderWorkflowService.ProcessServiceResult reply = new OrderWorkflowService.ProcessServiceResult();
                //reply.POID = po.POID;
                //reply.Message = "The order has been processed successfully.";
    
                //lock (workItem.WorkItemLock)
                //{
                //    using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
                //    {
                //        client.SubmitProcessResult(reply);
                //    }
    
                //    workItem.Complete();
                //    WorkItemMap.Remove(po.POID);
                //}
    
            }
    
            public string CancelOrderProcess(string poID)
            {
                string ret = "Cancel unavailable for this order.";
    
                //=====================================================//
                //===[ Attempt to get a work item for the order Id 
                //=====================================================//
                WorkItem workItem;
                if (WorkItemMap.TryGetValue(poID, out workItem) == true)
                {
                    //===========================================================
                    //=== Slight race condition here. Workitem could complete
                    //=== before we aquire its lock. So we check the          
                    //=== completion flag inside the lock.                    
                    //===========================================================
                    lock (workItem.WorkItemLock)
                    {
                        if ((!workItem.CompleteFlag) && (workItem.WorkThread.IsAlive))
                        {
                            workItem.WorkThread.Abort();
                            WorkItemMap.Remove(poID);
                            ret = "The order process has been terminated successfully.";
                        }
                    }
                }
                return ret;
            }
        }
    }
    

構成ファイルを使用することによって、エンドポイントとサービス ビヘイビアーのデータを、設計時ではなく、展開時に指定できるようになります。この構成ファイルで、2 つのエンドポイントを定義します。

構成ファイルを使用して Order Process サービスを構成するには

  1. ソリューション エクスプローラーで、OrderProcessingService を展開し、Web.config をダブルクリックして開きます。<services> を <system.serviceModel> タグ内に追加します。

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.OrderProcessing">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.IOrderProcessing" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Order Process WCF サービスをコンパイルするには

  1. ソリューション エクスプローラーで、OrderProcessingService プロジェクトを右クリックし、[リビルド] をクリックします。出力ウィンドウでプロジェクトが正しくコンパイルされたことを確認します。

Order Process WCF サービスをテストするには

  1. ソリューション エクスプローラーで、OrderProcessingService プロジェクトを右クリックし、[ブラウザーで表示] をクリックします。Internet Explorer ウィンドウが開き、ディレクトリ ファイルの一覧が表示されます。

  2. Internet Explorer ウィンドウで、OrderProcessing.svc をクリックします。何もエラーが表示されないことを確認します。

Shipping WCF サービスの開発

Shipping サービスは、SQL Server ストアを呼び出す WCF サービスです。シミュレーションでは、実際にはデータベースの呼び出しは行いません。

新しい WCF サービス アプリケーション プロジェクトをソリューションに追加するには

  1. ソリューション エクスプローラーで、ソリューション 'OrderService' を右クリックし、[追加] をポイントして、[新しいプロジェクト] をクリックします。

  2. [新しいプロジェクトの追加] ダイアログ ボックスで、以下の値を選択または入力し、[OK] をクリックします。

    プロパティ

    プロジェクトの種類

    Visual C#/Web

    テンプレート

    WCF サービス アプリケーション

    プロジェクト名

    ShippingService

    場所

    C:\DublinTutorial\OrderServiceSolution\OrderService

  3. ソリューション エクスプローラーで、ShippingService を展開し、IService1.cs を右クリックして、[削除] をクリックします。

  4. ファイルを完全に削除することを確認するメッセージが表示されたら、[OK] をクリックします。

  5. ソリューション エクスプローラーで、ShippingService を展開し、Service1.svc を右クリックして、[削除] をクリックします。

  6. ファイルを完全に削除することを確認するメッセージが表示されたら、[OK] をクリックします。

IShipping という名前のサービス コントラクトを定義します。このコントラクトには、ShipOrder と CancelShipping の 2 つの操作コントラクトが含まれます。

Shipping WCF サービス コントラクトを定義するには

  1. ソリューション エクスプローラーで、ShippingService を右クリックし、[追加] をポイントして、[新しい項目] をクリックします。

  2. [新しい項目の追加 - ShippingService] ダイアログ ボックスで、以下の値を選択または入力し、[追加] をクリックします。

    プロパティ

    カテゴリ

    Visual C#/Web

    テンプレート

    WCF サービス

    ファイル名

    Shipping.svc

    プロジェクトに IShipping.cs と Shipping.svc の 2 つのファイルが追加されます。

  3. ソリューション エクスプローラーで、IShipping.cs をダブルクリックして開きます。

  4. ShippingService 名前空間を右クリックし、[リファクター] をクリックし、[名前の変更] をクリックして、[名前の変更] ダイアログ ボックスを開きます。

  5. [新しい名前] ボックスに、「Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService」と入力し、[OK] をクリックします。

  6. [適用] をクリックし、[はい] をクリックします。

  7. ソース コードを、次のように変更します。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService
    {
        [ServiceContract]
        public interface IShipping
        {
            [OperationContract]
            string ShipOrder(string poID);
    
            [OperationContract]
            string CancelShipping(string poID);
        }
    }
    

Shipping WCF サービス コントラクトを実装するには

  1. ソリューション エクスプローラーで、Shipping.svc をダブルクリックして開きます。

  2. ソース コードを、次のように変更します。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Threading;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService
    {
        class WorkItem
        {
            private Thread workThread;
            private object workItemLock;
            private bool completeFlag;
    
            public Thread WorkThread { get { return workThread; } set { workThread = value; } }
            public object WorkItemLock { get { return workItemLock; } }
            public bool CompleteFlag { get { return completeFlag; } }
    
            public WorkItem(Thread WorkThread)
            {
                workThread = WorkThread;
                workItemLock = new object();
                completeFlag = false;
            }
    
            public void Complete()
            {
                completeFlag = true;
            }
        }
    
        public class Shipping : IShipping
        {
            private static Dictionary<String, WorkItem> WorkItemMap = new Dictionary<String, WorkItem>();
    
            public string ShipOrder(string poID)
            {
                //run the code from a different thread to simulate asynchronized call
                ThreadPool.QueueUserWorkItem(SendShippingResult, poID);
                return ("The request for processing order[" + poID + "] has been received.");
            }
    
            private void SendShippingResult(object state)
            {
                string poID = state.ToString();
    
                WorkItem workItem = new WorkItem(Thread.CurrentThread);
                WorkItemMap.Add(poID, workItem);
    
                //Simulating the order processing process
                Thread.Sleep(60000);
    
                //The following portion will be uncommented after referencing OrderWorkflowService
                //OrderWorkflowService.ShippingServiceResult reply = new OrderWorkflowService.ShippingServiceResult();
                //reply.POID = poID;
                //reply.Message = "The order has been shipped.";
    
                //lock (workItem.WorkItemLock)
                //{
                //    using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
                //    {
                //        client.SubmitShippingResult(reply);
                //    }
    
                //    workItem.Complete();
                //    WorkItemMap.Remove(poID);
                //}
            }
    
            public string CancelShipping(string poID)
            {
                string ret = "Cancel unavailable for this order.";
    
                //=====================================================//
                //===[ Attempt to get a work item for the order Id 
                //=====================================================//
                WorkItem workItem;
                if (WorkItemMap.TryGetValue(poID, out workItem) == true)
                {
                    //===========================================================
                    //=== Slight race condition here. Workitem could complete
                    //=== before we aquire its lock. So we check the          
                    //=== completion flag inside the lock.                    
                    //===========================================================
                    lock (workItem.WorkItemLock)
                    {
                        if ((!workItem.CompleteFlag) && (workItem.WorkThread.IsAlive))
                        {
                            workItem.WorkThread.Abort();
                            WorkItemMap.Remove(poID);
                            ret = "The shipping process has been terminated successfully.";
                        }
                    }
                }
                return ret;
            }
        }
    }
    

この構成ファイルで、2 つのエンドポイントを定義します。

構成ファイルを使用して Shipping WCF サービスを構成するには

  1. ソリューション エクスプローラーで、ShippingService を展開し、Web.config をダブルクリックして開きます。<services> を <system.serviceModel> タグ内に追加します。

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Shipping">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.IShipping" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Shipping WCF サービスをコンパイルするには

  1. ソリューション エクスプローラーで、ShippingService プロジェクトを右クリックし、[リビルド] をクリックします。出力ウィンドウでプロジェクトが正しくコンパイルされたことを確認します。

Order Workflow WF サービスの開発

Order ワークフロー サービス アプリケーションは、このサービス全体の主要な部分です。ビジネス プロセス全体の調整を行います。このアプリケーションは、注文を受け取ると、OrderProcessingService および ShippingService を呼び出して、最終的には顧客に注文の状況に関する電子メール メッセージを送信します。

新しい WCF ワークフロー サービス アプリケーション プロジェクトをソリューションに追加するには

  1. ソリューション エクスプローラーで、ソリューション 'OrderService' を右クリックし、[追加] をポイントして、[新しいプロジェクト] をクリックします。

  2. [新しいプロジェクトの追加] ダイアログ ボックスで、以下の値を選択または入力し、[OK] をクリックします。

    プロパティ

    プロジェクトの種類

    Visual C#/Workflow

    テンプレート

    WCF ワークフロー サービス アプリケーション

    プロジェクト名

    OrderWorkflowService

    場所

    C:\DublinTutorial\OrderServiceSolution\OrderService

OrderWorkflowService は、OrderProcessingService と ShippingService を利用します。この 2 つのサービスを参照する必要があります。

サービス参照を追加するには

  1. ソリューション エクスプローラーで、OrderWorkflowService を右クリックし、[サービス参照の追加] をクリックします。

  2. [サービス参照の追加] ダイアログ ボックスで、[探索] をクリックします。Visual Studio で、両方のサービスが探索されます。

  3. 以下の値を入力および選択し、[OK] をクリックしてサービス参照を作成します。

    プロパティ

    サービス

    OrderProcessing.svc

    名前空間

    OrderProcessService

  4. 以下の値を使用して、もう 1 つのサービス参照についても同じ手順を繰り返します。

    プロパティ

    サービス

    Shipping

    名前空間

    ShippingService

電子メール通知の送信をシミュレートするために使用するカスタム ワークフロー アクティビティを定義する必要があります。

ワークフロー コード アクティビティを作成するには

  1. ソリューション エクスプローラーで、OrderWorkflowService を右クリックし、[追加] をポイントして、[新しい項目] をクリックします。

  2. [新しい項目の追加 - OrderWorkflowService] ダイアログ ボックスで、以下の値を選択または入力し、[追加] をクリックします。

    プロパティ

    カテゴリ

    Visual C#/Workflow

    テンプレート

    コード アクティビティ

    ファイル名

    SendNotification.cs

  3. ソリューション エクスプローラーで、SendNotification.cs をダブルクリックして開きます。

  4. OrderWorkflowService 名前空間を右クリックし、[リファクター] をクリックし、[名前の変更] をクリックして、[名前の変更] ダイアログ ボックスを開きます。

  5. [新しい名前] ボックスに、「Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService」と入力し、[OK] をクリックします。

  6. [適用] をクリックし、[はい] をクリックします。

  7. ソース コードを、次のように変更します。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Activities;
    using System.IO;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService
    {
        public class SendNotification : CodeActivity
        {
            InArgument<string> to;
            InArgument<string> subject;
            InArgument<string> body;
            string pathRoot = @"C:\DublinTutorial\Inbox\";
    
            public InArgument<string> To { get { return this.to; } set { this.to = value; } }
            public InArgument<string> Subject { get { return this.subject; } set { this.subject = value; } }
            public InArgument<string> Body { get { return this.body; } set { this.body = value; } }
            public SendNotification() { }
    
            public SendNotification(InArgument<string> To, InArgument<string> Subject, InArgument<string> Body)
            {
                this.to = To; this.subject = Subject; this.body = Body;
            }
    
            protected override void Execute(CodeActivityContext context)
            {
                string filename;
                string content;
    
                try
                {
                    filename = this.to.Get<String>(context) + "~~" + this.subject.Get<string>(context) + "_" + DateTime.Now.ToFileTime() + ".txt";
                    content = String.Format("To: {0}" + Environment.NewLine
                        + "From: {1}" + Environment.NewLine
                        + "Subject: {2}" + Environment.NewLine
                        + Environment.NewLine
                        + "{3}",
                        this.to.Get<String>(context), "CustomerRelations@Contoso.com", this.subject.Get<String>(context), this.body.Get<String>(context));
    
                    File.WriteAllText((pathRoot + filename), content);
                }
                catch (Exception Ex)
                {
                    context.SetValue(Body, Ex.Message);
                }
    
            }
        }
    }
    

    パスが "C:\DublinTutorial\Inbox\" のようにハードコーディングされている点に注意してください。

次の手順では、データ型を定義します。これらのデータ型は、OrderProcessingService と ShippingService で結果を OrderWorkflowService に返すために使用されます。

データ型を定義するには

  1. ソリューション エクスプローラーで、OrderWorkflowService を右クリックし、[追加] をポイントして、[新しい項目] をクリックします。

  2. [新しい項目の追加 - OrderWorkflowService] ダイアログ ボックスで、以下の値を選択または入力し、[追加] をクリックします。

    プロパティ

    カテゴリ

    Visual C#/コード

    テンプレート

    コード ファイル

    ファイル名

    DataTypes.cs

  3. ソリューション エクスプローラーで、DataTypes.cs をダブルクリックして開きます。

  4. ソース コードを、次のように変更します。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService
    {
        [DataContract]
        public class ProcessServiceResult
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string Message;
        }
    
        [DataContract]
        public class ShippingServiceResult
        {
            [DataMember]
            public string POID;
            [DataMember]
            public string Message;
        }
    }
    
  5. ソリューション エクスプローラーで、OrderWorkflowService を右クリックし、[リビルド] をクリックします。次の手順で開発するワークフローからコード アクティビティにアクセスできるように、プロジェクトをビルドする必要があります。コンパイルによって、参照されている WCF サービス エンドポイントをワークフローに公開することもできます。

次の手順は、ワークフローを定義することです。ワークフローには、複数の状態が含まれます。最初に状態を定義し、次に状態の詳細を定義します。開発の各部分には、以下の手順が含まれる場合があります。

  1. アクティビティを使用してワークフローを構成します。

  2. 変数を定義します。

  3. アクティビティを構成します。

ワークフローを定義するには

  1. ソリューション エクスプローラーで、OrderWorkflowService を展開し、Service1.xamlx を右クリックして、[名前の変更] をクリックします。ファイル名を OrderWorkflow.xamlx に変更します。

  2. ソリューション エクスプローラーで、OrderWorkflow.xamlx をダブルクリックして開きます。Sequential Service に 2 つのアクティビティが表示されます。1 つは ReceiveRequest で、もう 1 つは SendResponse です。

  3. Sequential Service アクティビティを右クリックし、[削除] をクリックします。

  4. ワークフローで、[ここにアクティビティをドロップ] をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    configurationName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow

    Name

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow

  5. ウィンドウの左側にある [ツールボックス] をクリックして [ツールボックス] パネルを開き、ウィンドウの左側に固定表示します。

  6. ツールボックスから以下のアクティビティを、ワークフローの "ここにアクティビティをドロップ" と表示されている場所にドラッグします。

    カテゴリ アクティビティ

    フローチャート

    Flowchart

    Flowchart アクティビティは、既定では Start を含む複合アクティビティです。以下の手順で、さらにアクティビティを追加します。

  7. ツールボックスから以下のアクティビティを、示されている順序でワークフローにドラッグします。

    カテゴリ アクティビティ

    メッセージング

    ReceiveAndSendReply

    これは "注文を待っている" 状態です。

    制御フロー

    Sequence

    これには、2 番目の "注文が行われた" 状態が含まれます。

    フローチャート

    FlowDecision

    FlowDecision アクティビティは、状態間の遷移を容易にします。

    制御フロー

    Sequence

    これには、3 番目の "注文が処理された" 状態が含まれます。

    フローチャート

    FlowDecision

    FlowDecision アクティビティは、状態間の遷移を容易にします。

    制御フロー

    Sequence

    これには、最後の "注文が完了した" 状態が含まれます。

  8. マウス ポインターを使用して、次のようにアクティビティを接続します。

    67e7c9dd-77e7-43be-ad5a-797b3b46f6e8

  9. ワークフローの下部にある [変数] をクリックして、[変数] パネルを開きます。

  10. [変数] パネルで、[変数の作成] をクリックし、以下の変数を作成します。

    変数名 変数の型 スコープ

    poID

    String

    Flowchart

    poID は GUID 番号です。poID は関連付けにも使用されます。

    isProcessed

    Boolean

    Flowchart

    注文が正常に処理されたかどうかを示すフラグです。

    isShipped

    Boolean

    Flowchart

    注文が出荷されたかどうかを示すフラグです。

    isUpdated

    Boolean

    Flowchart

    注文が顧客によって更新されたどうかを示すフラグです。

    po

    PurchaseOrder

    Flowchart

    これは、OrderProcessingService で定義されるカスタム データ型です。PO (注文) の情報が含まれます。

    poUpdate

    PurchaseOrder

    Flowchart

    これには、顧客が PO を更新しようとした場合に、更新された PO 情報が格納されます。

    correlationorderWorkflow

    CorrelationHandle

    Flowchart

    これは、サービスに接続するクライアントと、OrderProcessService および ShippingService に接続するサービスの両方で使用される関連付けハンドルです。

    作成された変数のスクリーンショットを以下に示します。

    9208977f-710c-460f-afd8-5c6bd8a792d9

  11. ワークフローで、Flowchart アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Order service

  12. ワークフローで、最初の Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Wait for order

  13. ワークフローで、2 番目の Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Order opened

  14. ワークフローで、3 番目の Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Order processed

  15. ワークフローで、4 番目の Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Order completed

  16. ワークフローで、最初の FlowDecision アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Condition

    isProcessed

    FalseLabel

    Updated

    TrueLabel

    Processed

  17. ワークフローで、2 番目の FlowDecision アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Condition

    isShipped

    FalseLabel

    Updated

    TrueLabel

    Shipped

    これで、ステート マシン ワークフローの主な構造が定義されました。次に、それぞれの状態を定義します。

  18. ワークフローで、Wait for order をダブルクリックします。タブの下にパスが表示されます。Order service をクリックして、ステート マシン ワークフロー全体が表示されるページに戻ることができます。

  19. ツールボックスから以下のアクティビティを、示されている順序でワークフローにドラッグします。

    カテゴリ アクティビティ

    プリミティブ

    Assign

    この Assign アクティビティは、注文と注文 ID (GUID) を取得します。

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowSerivce

    SendNotification

    このカスタム アクティビティは、クライアントに電子メール通知を送信します。

    プリミティブ

    Assign

    この Assign アクティビティは、注文の製品を監視できるようにするために使用されます。

    プリミティブ

    Assign

    この Assign アクティビティは、注文の数量を監視できるようにするために使用されます。

  20. アクティビティを次のように再配置します。

    注文待ち状態のアクティビティ

  21. ワークフローの下部にある [変数] をクリックして、[変数] パネルを開きます。

  22. [変数] パネルで、[変数の作成] をクリックし、以下の変数を作成します。

    変数名 変数の型 スコープ

    product

    String

    Wait for order

    AppFabric では、ワークフロー変数を追跡できます。この変数は、製品名を追跡できるようにするために作成します。

    quantity

    Int32

    Wait for order

    この変数は追跡のために使用されます。

  23. ワークフローで、Receive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: po、メッセージ型: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.Purchaseorder

    DisplayName

    Receive PO

    OperationName

    SubmitPO

    SerivceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (オン)

  24. ワークフローで、最初の Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Assign PO ID

    To

    po.POID

    Value

    System.Guid.NewGuid().ToString()

  25. ワークフローで、SendReplyToReceive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: po.POID、メッセージ型: string

    CorrelationInitializers

    CorrelationOrderWorkflow、クエリ関連付け初期化子、key1=sm:body()/xg0:string

    237be300-a94d-4b8e-a707-83f4d2041f6e

    ヒント

    ここで行った作業を、関連付けといいます。このワークフローには 7 つの受信アクティビティがあります。注文を受信するものが 1 つ、処理サービスの結果を受信するものが 1 つ、出荷サービスの結果を受信するものが 1 つ、クライアントの更新を受信するものが 2 つ、クライアントのキャンセルを受信するものが 2 つです。注文を受信した後、ワークフロー サービスは注文番号として GUID 番号を生成します。ワークフロー サービスが多くの注文を同時に受信した場合を考えてみてください。ワークフロー エンジンは、注文要求のそれぞれについてワークフロー インスタンスを作成します。ワークフロー エンジンは、他の 6 つの要求をワークフロー インスタンスに対応付ける (つまり関連付ける) 必要があります。これを実現するために、ワークフロー エンジンは各関連付けについて一意の識別子を必要とします。このサンプルでは、一意の識別子は注文番号 (GUID) です。最初の SendReplyToReceive アクティビティでは、CorrelationInitializer を定義します。関連付けの種類としてクエリ関連付け初期化子を選択します。これは、一意の識別子が、受信アクティビティに渡されるメッセージに含まれることを意味します。また、フィールドに xPath も指定します。関連付け初期化子に加えて、CorrelateWith フィールドで関連付けハンドルも指定する必要があります。関連付けハンドルは、関連付けデータのコンテナーであり、ワークフロー内の任意の場所から関連付けデータを取得できるようにします。以降の受信では、同じ関連付けハンドルを指定します。CorrelateOn フィールドで、受信したメッセージから注文番号を取得する方法を指定します。

  26. ワークフローで、SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "We have received your order.  Your order number is " + po.POID

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Received"

    To

    po.EmailAddress

  27. ワークフローで、2 番目の Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Assign product name

    To

    proudct

    Value

    po.Description

  28. ワークフローで、3 番目の Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Assign quantity

    To

    quantity

    Value

    po.Quantity

    これで、Wait for order 状態の実装が完了しました。

  29. タブ名の下にある Order service をクリックし、"Order service" Flowchart アクティビティを表示します。

  30. ワークフローで、Order opened Sequence アクティビティをダブルクリックして状態を実装します。

  31. ツールボックスから以下のアクティビティを、示されている順序でワークフローにドラッグします。

    カテゴリ アクティビティ

    プリミティブ

    Assign

    制御フロー

    Parallel

  32. 以下のアクティビティを Parallel アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    制御フロー

    Sequence

  33. 以下のアクティビティを Sequence アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    ProcessOrder

    ランタイム

    Persist

    メッセージング

    Receive

    Microsoft.Samples.Dublin.Tutorials.OrderService.orderWorkflowService

    SendNotification

    プリミティブ

    Assign

  34. 以下のアクティビティを Parallel アクティビティ内の、既存の Sequence アクティビティの右側にドラッグします。

    カテゴリ アクティビティ

    メッセージング

    ReceiveAndSendReply

    ReceiveAndSendReply アクティビティは、Receive アクティビティと SendReplyToReceive アクティビティをラップする 1 つの Sequence アクティビティを含む複合アクティビティです。

  35. 以下のアクティビティを、新しく追加した Sequence アクティビティ内の、Receive と SendReplyToReceive の 2 つのアクティビティの下にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    CancelOrderProcess

    制御フロー

    If

  36. 以下のアクティビティを If アクティビティの Then 分岐内にドラッグします。

    カテゴリ アクティビティ

    制御フロー

    Sequence

  37. 以下のアクティビティを、新しく追加した Sequence アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    プリミティブ

    Assign

    プリミティブ

    Assign

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

  38. 以下のアクティビティを If アクティビティの Else 分岐内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

  39. 以下のアクティビティを Parallel アクティビティ内にドラッグして、一番右側の分岐を作成します。

    カテゴリ アクティビティ

    メッセージング

    ReceiveAndSendReply

  40. 以下のアクティビティを、新しく追加した Sequence アクティビティ内の、Receive と SendReplyToReceive の 2 つのアクティビティの下にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderProcessingService.Activities

    CancelOrderProcess

    制御フロー

    If

  41. 以下のアクティビティを If アクティビティの Then 分岐内にドラッグします。

    カテゴリ アクティビティ

    制御フロー

    Sequence

  42. 以下のアクティビティを、新しく追加した Sequence アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    ランタイム

    TerminateWorkflow

  43. 以下のアクティビティを If アクティビティの Else 分岐内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    アクティビティを追加した後の Order Opened 状態は次のようになります。

    注文オープン済み状態

  44. Parallel アクティビティの最も左側にあるブランチの Sequence アクティビティをクリックし、ワークフローの下部にある [変数] をクリックして、[変数] パネルを開きます。

  45. [変数] パネルで、[変数の作成] をクリックし、以下の変数を作成します。

    変数名 変数の型 スコープ

    cancelOrderProcessAcknowledgement

    String

    Parallel

    ProcessServiceResult

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ProcessServiceResult

    Sequence

    processServiceAcknowledgement

    String

    Sequence

  46. ワークフローで、Parallel アクティビティの上にある Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Initialize isUpdated

    To

    isUpdated

    Value

    False

  47. ワークフローで、Parallel アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Completion

    isUpdated Or isProcessed

    DisplayName

    Process order

  48. ワークフローで、Parallel アクティビティの最も左側の分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Processing

  49. ワークフローで、Parallel アクティビティの最も左側の分岐にある ProcessOrder アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Process order

    po

    po

    ProcessOrderResult

    processServiceAcknowledgement

  50. ワークフローで、Parallel アクティビティの最も左側の分岐にある Receive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ:processServiceResult、メッセージ型: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ProcessServiceResult

    DisplayName

    Receive process result

    OperationName

    SubmitProcessResult

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (オフ)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow、XPath クエリ: key1=sm:body()/xg0:ProcessServiceResult/sg0:POID

    CorrelationWith

    correlationOrderWorkflow

  51. ワークフローで、Parallel アクティビティの最も左側の分岐にある SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Order with order#" + po.POID + " has been processed, and is ready for shipping."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Processed"

    To

    po.EmailAddress
  52. ワークフローで、Parallel アクティビティの最も左側の分岐にある Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Set isProcessed flag

    To

    isProcessed

    Value

    True

    Parallel アクティビティの最も左側にある分岐の構成が完了しました。

  53. ワークフローで、Parallel アクティビティの中央の分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Waiting for update

  54. ワークフローで、Parallel アクティビティの中央の分岐にある Receive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: poUpdate、メッセージ型: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.PurchaseOrder

    DisplayName

    Receive update

    OperationName

    SubmitUpdate

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (オフ)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow、XPath クエリ: key1=sm:body()/xg0:PurchaseOrder/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  55. ワークフローで、Parallel アクティビティの中央の分岐にある SendReplyToReceive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: "PO update received"、メッセージ型: String

    DisplayName

    Acknowledge receiving update

  56. ワークフローで、Parallel アクティビティの中央の分岐にある CancelOrderProcess アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    CancelOrderProcessResult

    cancelOrderProcessAcknowledgement

    DisplayName

    Cancel order processing

    orderID

    po.POID
  57. ワークフローで、Parallel アクティビティの中央の分岐にある If アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Condition

    cancelOrderProcessAcknowledgement = "The order process has been terminated successfully."

    DisplayName

    Check cancellation status

  58. ワークフローで、If アクティビティの Then 分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Cancellation succeed sequence

  59. ワークフローで、If アクティビティの Then 分岐にある最初の Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Refresh PO

    To

    po

    Value

    poUpdate
  60. ワークフローで、If アクティビティの Then 分岐にある 2 番目の Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Set isUpdated flag

    To

    isUpdated

    Value

    True
  61. ワークフローで、If アクティビティの Then 分岐にある SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order has updated upon your request. The order is under processing."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Updated (by customer)"

    To

    po.EmailAddress
  62. ワークフローで、If アクティビティの Else 分岐にある SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order update request cannot be processed. Please try again."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Update (by customer) Failed"

    To

    po.EmailAddress

    Parallel アクティビティの中央にある分岐の構成が完了しました。

  63. ワークフローで、Parallel アクティビティの最も右側の分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Waiting for cancellation

  64. ワークフローで、Parallel アクティビティの最も右側にある Receive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: poID、メッセージ型: String

    DisplayName

    Receive cancellation

    OperationName

    SubmitCancellation

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (オフ)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow、XPath クエリ: key1=sm:body()/xg0:string

    CorrelationWith

    correlationOrderWorkflow

  65. ワークフローで、Parallel アクティビティの最も右側の分岐にある SendReplyToReceive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: "PO cancellation received"、メッセージ型: String

    DisplayName

    Acknowledge receiving cancellation

  66. ワークフローで、Parallel アクティビティの最も右側にある CancelOrderProcess アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    CancelOrderProcessResult

    cancelOrderProcessAcknowledgement

    DisplayName

    Cancel order processing

    orderID

    po.POID
  67. ワークフローで、Parallel アクティビティの最も右側にある If アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Condition

    cancelOrderProcessAcknowledgement = "The order process has been terminated successfully."

    DisplayName

    Check cancellation status

  68. ワークフローで、If アクティビティの Then 分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Cancellation succeed sequence

  69. ワークフローで、If アクティビティの Then 分岐にある SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order has been cancelled upon your request."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancelled (by customer)"

    To

    po.EmailAddress
  70. ワークフローで、If アクティビティの Then 分岐にある TerminateWorkflow アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Terminate workflow

    Reason

    “Client cancellation”
  71. ワークフローで、If アクティビティの Else 分岐にある 2 番目の SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order cancellation request cannot be processed. Please try again."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancellation(by customer) Failed"

    To

    po.EmailAddress

    Parallel アクティビティの最も右側にある分岐の構成が完了しました。

  72. タブ名の下にある Order service をクリックし、"Order service" Flowchart アクティビティを表示します。

  73. ワークフローで、Order processed Sequence アクティビティをダブルクリックして状態を実装します。

  74. ツールボックスから以下のアクティビティを、示されている順序でワークフローにドラッグします。

    カテゴリ アクティビティ

    プリミティブ

    Assign

    制御フロー

    Parallel

  75. 以下のアクティビティを Parallel アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    制御フロー

    Sequence

  76. 以下のアクティビティを Sequence アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    ShipOrder

    ランタイム

    Persist

    メッセージング

    Receive

    プリミティブ

    Assign

  77. 以下のアクティビティを Parallel アクティビティ内の、既存の Sequence アクティビティの右側にドラッグします。

    カテゴリ アクティビティ

    メッセージング

    ReceiveAndSendReply

    ReceiveAndSendReply アクティビティは、Receive アクティビティと SendReplyToReceive アクティビティをラップする 1 つの Sequence アクティビティを含む複合アクティビティです。

  78. 以下のアクティビティを、新しく追加した Sequence アクティビティ内の、Receive と SendReplyToReceive の 2 つのアクティビティの下にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    CancelShipping

    制御フロー

    If

  79. 以下のアクティビティを If アクティビティの Then 分岐内にドラッグします。

    カテゴリ アクティビティ

    制御フロー

    Sequence

  80. 以下のアクティビティを、新しく追加した Sequence アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    プリミティブ

    Assign

    プリミティブ

    Assign

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  81. 以下のアクティビティを If アクティビティの Else 分岐内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  82. 以下のアクティビティを Parallel アクティビティ内にドラッグして、一番右側の分岐を作成します。

    カテゴリ アクティビティ

    メッセージング

    ReceiveAndSendReply

  83. 以下のアクティビティを、新しく追加した Sequence アクティビティ内の、Receive と SendReplyToReceive の 2 つのアクティビティの下にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.ShippingService.Activities

    CancelShipping

    制御フロー

    If

  84. 以下のアクティビティを If アクティビティの Then 分岐内にドラッグします。

    カテゴリ アクティビティ

    制御フロー

    Sequence

  85. 以下のアクティビティを、新しく追加した Sequence アクティビティ内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

    ランタイム

    TerminateWorkflow

  86. 以下のアクティビティを If アクティビティの Else 分岐内にドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SenNotification

    アクティビティを追加した後の Order Processed 状態は次のようになります。

    注文処理済み状態

  87. Parallel アクティビティの最も左側にあるブランチの Sequence アクティビティをクリックし、ワークフローの下部にある [変数] をクリックして、[変数] パネルを開きます。

  88. [変数] パネルで、[変数の作成] をクリックし、以下の変数を作成します。

    変数名 変数の型 スコープ

    cancelShippingAcknowledgement

    String

    Parallel

    ShippingServiceResult

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ShippingServiceResult

    Sequence

    shippingServiceAcknowledgement

    String

    Sequence

  89. ワークフローで、Parallel アクティビティの上にある Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Initialize isUpdated

    To

    isUpdated

    Value

    False

  90. ワークフローで、Parallel アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Completion

    isUpdated Or isShipped

    DisplayName

    Ship order

  91. ワークフローで、Parallel アクティビティの最も左側の分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Shipping

  92. ワークフローで、Parallel アクティビティの最も左側の分岐にある ShipOrder アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Ship order

    poID

    po.POID

    ShipOrderResult

    shippingServiceAcknowledgement

  93. ワークフローで、Parallel アクティビティの最も左側の分岐にある Receive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: shippingServiceResult、メッセージ型: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.ShippingServiceResult

    DisplayName

    Receive shipping result

    OperationName

    SubmitShippingResult

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (オフ)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow、XPath クエリ: key1=sm:body()/xg0:ShippingServiceResult/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  94. ワークフローで、Parallel アクティビティの最も左側の分岐にある Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Set isShipped flag

    To

    isShipped

    Value

    True

    Parallel アクティビティの最も左側にある分岐の構成が完了しました。

  95. ワークフローで、Parallel アクティビティの中央の分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Waiting for update

  96. ワークフローで、Parallel アクティビティの中央の分岐にある Receive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: poUpdate、メッセージ型: Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderProcessingService.PurchaseOrder

    DisplayName

    Receive update

    OperationName

    SubmitUpdate

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (オフ)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow、XPath クエリ: key1=sm:body()/xg0:PurchaseOrder/xg0:POID

    CorrelationWith

    correlationOrderWorkflow

  97. ワークフローで、Parallel アクティビティの中央の分岐にある SendReplyToReceive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: "PO update received"、メッセージ型: String

    DisplayName

    Acknowledge receiving update

  98. ワークフローで、Parallel アクティビティの中央の分岐にある CancelShipping アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    CancelShippingResult

    cancelShippingAcknowledgement

    DisplayName

    Cancel shipping

    orderID

    poUpdate.POID
  99. ワークフローで、Parallel アクティビティの中央の分岐にある If アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Condition

    cancelShippingAcknowledgement = "The shipping process has been terminated successfully."

    DisplayName

    Check cancellation status

  100. ワークフローで、If アクティビティの Then 分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Cancellation succeed sequence

  101. ワークフローで、If アクティビティの Then 分岐にある最初の Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Refresh PO

    To

    po

    Value

    poUpdate
  102. ワークフローで、If アクティビティの Then 分岐にある 2 番目の Assign アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Set isUpdated flag

    To

    isUpdated

    Value

    True
  103. ワークフローで、If アクティビティの Then 分岐にある SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order has updated upon your request. The order is under processing."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Updated (by customer)"

    To

    po.EmailAddress
  104. ワークフローで、If アクティビティの Else 分岐にある SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order update request cannot be processed. The order has been shipped."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Update (by customer) Failed"

    To

    po.EmailAddress

    Parallel アクティビティの中央にある分岐の構成が完了しました。

  105. ワークフローで、Parallel アクティビティの最も右側の分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Waiting for cancellation

  106. ワークフローで、Parallel アクティビティの最も右側にある Receive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: poID、メッセージ型: String

    DisplayName

    Receive cancellation

    OperationName

    SubmitCancellation

    ServiceContractName

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService

    CanCreateInstance

    (オフ)

    CorrelationOn

    CorrelationWith: correlationOrderWorkflow、XPath クエリ: key1=sm:body()/xg0:string

    CorrelationWith

    correlationOrderWorkflow

  107. ワークフローで、Parallel アクティビティの最も右側の分岐にある SendReplyToReceive アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Content

    メッセージ、メッセージ データ: "PO cancellation received"、メッセージ型: String

    DisplayName

    Acknowledge receiving cancellation

  108. ワークフローで、Parallel アクティビティの最も右側にある CancelShipping アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    CancelshippingResult

    cancelShippingAcknowledgement

    DisplayName

    Cancel shipping

    poID

    po.POID
  109. ワークフローで、Parallel アクティビティの最も右側にある If アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Condition

    cancelShippingAcknowledgement = "The shipping process has been terminated successfully."

    DisplayName

    Check cancellation status

  110. ワークフローで、If アクティビティの Then 分岐にある Sequence アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Cancellation succeed sequence

  111. ワークフローで、If アクティビティの Then 分岐にある SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "We are sorry you chose to cancel your order. If there is anything we can do to help you with our order process or with our products or services please do not hesitate to contact us."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancelled (by cusotmer)"

    To

    po.EmailAddress
  112. ワークフローで、If アクティビティの Then 分岐にある TerminateWorkflow アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    DisplayName

    Terminate workflow

    Reason

    “Client cancellation”
  113. ワークフローで、If アクティビティの Else 分岐にある 2 番目の SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order cancellation request cannot be processed. The order has been shipped.

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~Order Cancellation(by customer) Failed"

    To

    po.EmailAddress

    Parallel アクティビティの最も右側にある分岐の構成が完了しました。

  114. タブ名の下にある Order service をクリックし、"Order service" Flowchart アクティビティを表示します。

  115. ワークフローで、Order completed Sequence アクティビティをダブルクリックして状態を実装します。

  116. ツールボックスから以下のアクティビティを、示されている順序でワークフローにドラッグします。

    カテゴリ アクティビティ

    Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService

    SendNotification

  117. ワークフローで、If アクティビティの Else 分岐にある 2 番目の SendNotification アクティビティをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Body

    "Your order has been shipped.  Thank you for shopping at contoso.com."

    DisplayName

    Send client notification

    Subject

    "Contoso.com Order#" + po.POID + "~~ Order Shipped"

    To

    po.EmailAddress

    これで、ワークフローの開発が完了しました。

この構成ファイルで、2 つのエンドポイントと 1 つの behavior 要素を定義します。

構成ファイルを使用して Order Workflow サービスを構成するには

  1. ソリューション エクスプローラーで、OrderWorkflowService を展開し、Web.config をダブルクリックして開きます。

  2. <services><system.serviceModel> タグ内に追加します。

        <services>
          <service name="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.OrderWorkflow">
            <endpoint address="" binding="basicHttpBinding" contract="Microsoft.Samples.Dublin.Tutorials.OrderService.OrderWorkflowService.IOrderWorkflowService" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    

Order Workflow サービスをコンパイルするには

  1. ソリューション エクスプローラーで、OrderWorkflowService プロジェクトを右クリックし、[リビルド] をクリックします。出力ウィンドウでプロジェクトが正しくコンパイルされたことを確認します。

Order Processing WCF サービスの完成

OrderProcessingService と OrderWorkflowService は相互に参照します。したがって、OrderWorkflowService を完成させた後、OrderProcessingService を完成させる必要があります。

サービス参照を追加するには

  1. ソリューション エクスプローラーで、OrderProcessingService を右クリックし、[サービス参照の追加] をクリックします。

  2. [サービス参照の追加] ダイアログ ボックスで、[探索] をクリックします。Visual Studio で、両方のサービスが探索されます。

  3. 以下の値を入力および選択し、[OK] をクリックしてサービス参照を作成します。

    プロパティ

    サービス

    OrderWorkflow.xamlx

    名前空間

    OrderWorkflowService

OrderProcess.svc を変更するには

  1. ソリューション エクスプローラーで、OrderProcessingService を展開し、OrderProcessing.svc をダブルクリックして開きます。

  2. SendProcessResult 関数内のセクションのコメントを解除します。この関数は次のようになります。

    
    private void SendProcessResult(object state)
    {
        PurchaseOrder po = (PurchaseOrder)state;
    
        WorkItem workItem = new WorkItem(Thread.CurrentThread);
        WorkItemMap.Add(po.POID, workItem);
    
        //Simulating the order processing process
        Thread.Sleep(120000);
    
        //The following portion will be uncommented after referencing OrderWorkflowService
        OrderWorkflowService.ProcessServiceResult reply = new OrderWorkflowService.ProcessServiceResult();
        reply.POID = po.POID;
        reply.Message = "The order has been processed successfully.";
    
        lock (workItem.WorkItemLock)
        {
            using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
            {
                client.SubmitProcessResult(reply);
            }
    
            workItem.Complete();
            WorkItemMap.Remove(po.POID);
        }
    
    }
    

Order Processing サービスをコンパイルするには

  1. ソリューション エクスプローラーで、OrderProcessingService プロジェクトを右クリックし、[リビルド] をクリックします。出力ウィンドウでプロジェクトが正しくコンパイルされたことを確認します。

Shipping サービスの完成

ShippingService と OrderWorkflowService は相互に参照します。したがって、OrderWorkflowService を完成させた後、ShipingService を完成させる必要があります。

サービス参照を追加するには

  1. ソリューション エクスプローラーで、ShippingService を右クリックし、[サービス参照の追加] をクリックします。

  2. [サービス参照の追加] ダイアログ ボックスで、[探索] をクリックします。Visual Studio で、両方のサービスが探索されます。

  3. 以下の値を入力および選択し、[OK] をクリックしてサービス参照を作成します。

    プロパティ

    サービス

    OrderWorkflow.xamlx

    名前空間

    OrderWorkflowService

Shipping.svc を変更するには

  1. ソリューション エクスプローラーで、ShippingService を展開し、Shipping.svc をダブルクリックして開きます。

  2. SendShippingResult 関数内のセクションのコメントを解除します。この関数は次のようになります。

    private void SendShippingResult(object state)
    {
        string poID = state.ToString();
    
        WorkItem workItem = new WorkItem(Thread.CurrentThread);
        WorkItemMap.Add(poID, workItem);
    
        //Simulating the order processing process
        Thread.Sleep(60000);
    
        //The following portion will be uncommented after referencing OrderWorkflowService
        OrderWorkflowService.ShippingServiceResult reply = new OrderWorkflowService.ShippingServiceResult();
        reply.POID = poID;
        reply.Message = "The order has been shipped.";
    
        lock (workItem.WorkItemLock)
        {
            using (OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient())
            {
                client.SubmitShippingResult(reply);
            }
    
            workItem.Complete();
            WorkItemMap.Remove(poID);
        }
    }
    

Shipping サービスをコンパイルするには

  1. ソリューション エクスプローラーで、ShippingService プロジェクトを右クリックし、[リビルド] をクリックします。出力ウィンドウでプロジェクトが正しくコンパイルされたことを確認します。

Order クライアント アプリケーションの開発

この手順では、Windows フォーム クライアント アプリケーションを開発します。

Windows フォーム アプリケーション プロジェクトをソリューションに追加するには

  1. ソリューション エクスプローラーで、ソリューション 'OrderService' を右クリックし、[追加] をポイントして、[新しいプロジェクト] をクリックします。

  2. [新しいプロジェクトの追加] ダイアログ ボックスで、以下の値を選択または入力し、[OK] をクリックします。

    プロパティ

    プロジェクトの種類

    Visual C#/Windows

    テンプレート

    Windows フォーム アプリケーション

    プロジェクト名

    OrderClient

    場所

    C:\DublinTutorial\OrderServiceSolution\OrderService

Order クライアントは、ワークフロー サービスへのインターフェイスです。ワークフロー サービスへのサービス参照を追加する必要があります。

サービス参照を追加するには

  1. ソリューション エクスプローラーで、OrderClient を右クリックし、[サービス参照の追加] をクリックして [サービス参照の追加] ダイアログ ボックスを開きます。

  2. [サービス参照の追加] ダイアログ ボックスで、[探索] をクリックします。

  3. 以下の値を入力および選択し、[OK] をクリックしてサービス参照を作成します。

    プロパティ

    サービス

    OrderWorkflow.xamlx

    名前空間

    OrderWorkflowService

Windows フォームを開発するには

  1. ソリューション エクスプローラーで、OrderClient を展開し、Form1.cs をダブルクリックして開きます。

  2. Form1.cs を右クリックし、[名前の変更] をクリックして「OrderForm.cs」と入力します。

  3. 確認メッセージが表示されたら、[はい] をクリックします。

  4. ツールボックスから、4 つの Label コントロール、5 つの TextBox コントロール、3 つの Button コントロールをフォームに追加します。

  5. ワークフローで、フォームをクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    OrderForm

    Text

    Contoso.com Order Form

  6. ワークフローで、label1 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    lblOrderNumber

    Text

    Order number:

  7. ワークフローで、label2 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    lblEmail

    Text

    Email:

  8. ワークフローで、label3 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    lblDescription

    Text

    Description:

  9. ワークフローで、label4 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    lblQuantity

    Text

    Quantity:

  10. ワークフローで、textbox1 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    txtOrderNumber

    Enabled

    False

  11. ワークフローで、textbox2 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    txtEmail

    Text

    JohnDole@fabrikam.com

  12. ワークフローで、textbox3 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    txtDescription

    Text

    Windows 7

  13. ワークフローで、textbox4 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    txtQuantity

    Text

    10

  14. ワークフローで、textbox5 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    txtStatus

    Anchor

    Bottom、Left、Right

    Enabled

    False

    Text

    “”

  15. ワークフローで、button1 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    btnSubmit

    Anchor

    Bottom、Right

    Text

    Submit

    Click ([イベント] タブの下)

    btnSubmit_Click

  16. ワークフローで、button2 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    btnUpdate

    Anchor

    Bottom、Right

    Text

    Update

    Click ([イベント] タブの下)

    btnUpdate_Click

  17. ワークフローで、button3 をクリックし、[プロパティ] パネルで以下の値を設定します。

    プロパティ

    Name

    btnCancel

    Anchor

    Bottom、Right

    Text

    Cancel

    Click ([イベント] タブの下)

    btnCancel_Click

  18. ソリューション エクスプローラーで、OrderForm.cs を右クリックし、[コードの表示] をクリックします。

  19. OrderClient 名前空間を右クリックし、[リファクター] をクリックし、[名前の変更] をクリックして、[名前の変更] ダイアログ ボックスを開きます。

  20. [名前の変更] ダイアログ ボックスで、「Microsoft.Samples.Dublin.Tutorials.OrderService.OrderClient」と入力し、[OK] をクリックします。

  21. [適用] をクリックします。

  22. コードを以下のコードに置き換えます。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Microsoft.Samples.Dublin.Tutorials.OrderService.OrderClient
    {
        public partial class OrderForm : Form
        {
            //Delegates to make all service calls on a secondary thread
            private delegate void SubmitOrderDelegate();
            private delegate void CancelOrderDelegate();
            private delegate void UpdateOrderDelegate();
            private delegate void CallbackDelegate(string poID, string str);
    
            private SubmitOrderDelegate SubmitOrderHandler;
            private CancelOrderDelegate CancelOrderHandler;
            private UpdateOrderDelegate UpdateOrderHandler;
            private CallbackDelegate CallbackHandler;
    
            public OrderForm()
            {
                InitializeComponent();
            }
    
            private void OrderForm_Load(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
                btnSubmit.Focus();
            }
    
            #region Submit button
            private void btnSubmit_Click(object sender, EventArgs e)
            {
                btnSubmit.Enabled = false;
                btnCancel.Enabled = false;
                btnUpdate.Enabled = false;
                txtEmail.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                SubmitOrderHandler = new SubmitOrderDelegate(this.SubmitOrder);
                SubmitOrderHandler.BeginInvoke(null, null);
            }
    
            private void SubmitOrder()
            {
                string strMessage = "Your order has been received.";
                string strPOID = "";
    
                OrderWorkflowService.PurchaseOrder po = new OrderWorkflowService.PurchaseOrder();
                po.EmailAddress = txtEmail.Text;
                po.Description = txtDescription.Text;
                po.Quantity = System.Int32.Parse(txtQuantity.Text);
    
                //A Blocking service call executed on secondary thread
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    strPOID = client.SubmitPO(po);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strMessage = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.SubmitOrderCallBack);
                this.BeginInvoke(CallbackHandler, strPOID, strMessage);
    
            }
    
            private void SubmitOrderCallBack(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                btnUpdate.Enabled = true;
                btnCancel.Enabled = true;
    
                txtOrderNumber.Text = strPOID;
                txtStatus.Text = strMessage;
            }
            #endregion
    
            #region Update button
            private void btnUpdate_Click(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                UpdateOrderHandler = new UpdateOrderDelegate(this.UpdateOrder);
                UpdateOrderHandler.BeginInvoke(null, null);
    
            }
    
            private void UpdateOrder()
            {
                string strMessage = "Your order update request has been received.";
                string strPOID = "";
    
                OrderWorkflowService.PurchaseOrder po = new OrderWorkflowService.PurchaseOrder();
                po.POID = txtOrderNumber.Text;
                po.EmailAddress = txtEmail.Text;
                po.Description = txtDescription.Text;
                po.Quantity = System.Int32.Parse(txtQuantity.Text);
    
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    strMessage = client.SubmitUpdate(po);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strMessage = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.UpdateOrderCallback);
                this.BeginInvoke(CallbackHandler, strPOID, strMessage);
    
            }
    
            private void UpdateOrderCallback(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                btnUpdate.Enabled = true;
                btnCancel.Enabled = true;
    
                txtStatus.Text = strMessage;
            }
            #endregion
    
            #region Cancel button
            private void btnCancel_Click(object sender, EventArgs e)
            {
                btnUpdate.Enabled = false;
                btnCancel.Enabled = false;
    
                txtStatus.Text = "Connecting to the Order service ...";
    
                //Executed on secondary thread so the UI thread is not blocked
                CancelOrderHandler = new CancelOrderDelegate(this.CancelOrder);
                CancelOrderHandler.BeginInvoke(null, null);
            }
    
            private void CancelOrder()
            {
                string strInOut = txtOrderNumber.Text;
    
                try
                {
                    OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient client = new OrderWorkflowService.MicrosoftSamplesDublinTutorialsOrderServiceOrderWorkflowServiceIOrderWorkflowServiceClient();
                    client.SubmitCancellation(ref strInOut);
                    client.Close();
                }
                catch (Exception Ex)
                {
                    strInOut = "Error: " + Ex.Message;
                }
    
                //Make UI updates back on the primary thread
                CallbackHandler = new CallbackDelegate(this.CancelOrderCallback);
                this.BeginInvoke(CallbackHandler, txtOrderNumber.Text, strInOut);
            }
    
            private void CancelOrderCallback(string strPOID, string strMessage)
            {
                //UI updates back on the primary thread
                //btnUpdate.Enabled = true;
                //btnCancel.Enabled = true;
    
                txtStatus.Text = strMessage;
            }
            #endregion
        }
    }
    

Order クライアントをコンパイルするには

  1. ソリューション エクスプローラーで、OrderClient プロジェクトを右クリックし、[リビルド] をクリックします。出力ウィンドウでプロジェクトが正しくコンパイルされたことを確認します。

Order サービスのテスト

Order サービスをテストするには

  1. ソリューション エクスプローラーで、OrderClient を右クリックし、[スタートアップ プロジェクトに設定] をクリックします。

  2. Visual Studio で、[デバッグ] メニューの [デバッグ開始] をクリックします。Windows フォームが表示されます。

  3. フォームで、[Submit] をクリックします。

  4. Windows エクスプローラーを開き、C:\DublinTutorial\Inbox フォルダーを参照します。

  5. 3 つの電子メール通知がすべて表示されるまで待ちます。3 つのファイルがすべて表示されるまでには、約 3 ~ 4 分かかります。

Order サービスのパッケージ

OrderProcessingService WCF サービスをパッケージするには

  1. ソリューション エクスプローラーで、OrderProcessingService プロジェクトを右クリックし、[パッケージ/発行の設定] をクリックします。

  2. 次の値を入力します。

    プロパティ

    Web パッケージを ZIP ファイルとして作成する

    (オン)

    パッケージを作成する場所

    C:\DublinTutorial\DeploymentPackages\OrderProcessingService.zip

    発行先サーバーで使用する IIS Web サイト/アプリケーション名

    OrderService/OrderProcessingService

  3. ソリューション エクスプローラーで、OrderProcessingService プロジェクトを右クリックし、[パッケージの作成] をクリックします。

  4. 最後の手順を繰り返して、以下の設定で他の 3 つのプロジェクトについてもパッケージを作成します。

    プロジェクト名 パッケージを作成する場所 発行先サーバーで使用する IIS Web サイト/アプリケーション名

    OrderWorkflowService

    C:\DublinTutorial\DeploymentPackages\OrderWorkflowService.zip

    OrderService/OrderWorkflowService

    ShippingService

    C:\DublinTutorial\DeploymentPackages\ShippingService.zip

    OrderService/ShippingService

    ヒント

    サービスをパッケージする前に、パッケージの展開先となるサーバーに合わせて、Web.config ファイルで依存サービスのエンドポイント アドレスを更新することも考慮してください。

関連項目

概念

AppFabric のインターフェイスの使用に関するチュートリアル
Windows PowerShell を使用したチュートリアル

  2012-03-05