このタスクでは、Windows Communication Foundation (WCF) コントラクトを実装し、サービスの状態情報を SQL データベースに保持する基本的なステート マシン ワークフロー サービスを作成します。この作業は、コントラクト優先の作成スタイルを使用して行います。
![]() |
---|
このワークフロー サービスは、このチュートリアルの残りの演習で使用します。 |
![]() |
---|
Visual Studio ワークフロー デザイナを使用してワークフロー サービスを作成または管理する場合、誤った検証エラーが発生することがあります。プロジェクトを正常に作成できる場合、このような検証エラーは無視してください。 |
ワークフロー サービスを設定してコントラクトを定義するには
Visual Studio 2008 を開き、[ファイル] の [新規作成] をポイントして [プロジェクト] をクリックします。
[新しいプロジェクト] ダイアログ ボックスの [WCF] で **[ステート マシンのワークフロー ライブラリ]**を選択します。
プロジェクトに WorkflowServiceTutorial という名前を付けて [OK] をクリックします。
Visual Studio 2008 によって、WCF サービスに使用されるものと同じスキーマを使用して構成設定を格納する App.config ファイル、コントラクト定義を含むソース ファイル、およびワークフローのデザイナ コードと実装コードを定義するワークフロー クラス ソース ファイルが生成されます。
2 つの StateActivity アクティビティを含むステート マシンのワークフローがテンプレートによって作成されます。最初の StateActivity アクティビティ (Workflow1InitialState) には、SetStateActivity アクティビティの後に ReceiveActivity アクティビティを含む EventDrivenActivity アクティビティが含まれています。SetStateActivity アクティビティの TargetStateName プロパティは、ステート マシンのワークフロー内のその他の StateActivity アクティビティ名に設定されています。
ReceiveActivity タイプそのものは、SequenceActivity から派生し、順番に実行される複数の子アクティビティを含むことができます。ReceiveActivity アクティビティの実装は標準の WCF サービス上への操作の実装に対応しますが、コードをメソッドの本体に実装するのではなく、WF アクティビティを介してアクションを実装します。
このチュートリアルの ReceiveActivity アクティビティにより、IWorkflow1.cs (Visual Basic ソリューションを作成した場合は IWorkflow1.vb) で定義されている新しい操作がいくつか実装されます。これらは要求/応答操作なので、クライアントはサーバーからメッセージを受信します。
これは、既に提供されている WCF コントラクトを使用するため、ワークフロー サービス作成のコントラクト優先スタイルと呼ばれます。新しいコントラクトをプログラムで作成する場合は、「How to: Implement a Windows Communication Foundation Contract Operation」を参照してください。
インターフェイス上で新しい操作を定義しようとしているため、IWorkflow1.cs (Visual Basic ソリューションを作成した場合は IWorkflow1.vb) を開き、既存のインターフェイス定義を次の例のコードで置き換えます。
<ServiceContract()> _ Public Interface IWorkflow1 <OperationContract()> _ Sub StartupService() <OperationContract()> _ Function Add(ByVal n1 As Integer) As Integer <OperationContract()> _ Function Subtract(ByVal n1 As Integer) As Integer <OperationContract()> _ Function Multiply(ByVal n1 As Integer) As Integer <OperationContract()> _ Function Divide(ByVal n1 As Integer) As Integer <OperationContract()> _ Sub ShutdownService() End Interface
[ServiceContract] public interface IWorkflow1 { [OperationContract] void StartupService(); [OperationContract] int Add(int n1); [OperationContract] int Subtract(int n1); [OperationContract] int Multiply(int n1); [OperationContract] int Divide(int n1); [OperationContract] void ShutdownService(); }
サービス コントラクトを実装するには
ワークフロー デザイナが表示されていない場合は、Workflow1.cs (Visual Basic ソリューションを作成した場合は Workflow1.vb) を右クリックし、[デザイナの表示] をクリックして、デザイナを開きます。
StateActivity アクティビティをステート マシン ワークフローにドラッグします。アクティビティの名前を OperationsState に変更します。
stateActivity1 の名前を FinalState に変更します。
メモ :
このアクティビティの名前を変更すると、アクティビティはワークフローに対して完了状態としてフラグされなくなるので、ワークフロー デザイナで FinalState を右クリックして [完了済みの状態として設定] をクリックします。 Workflow1InitialState StateActivity アクティビティで、eventDrivenActivity1 を選択して名前を WaitToStartService に変更します。
WaitToStartService をダブルクリックして展開します。ReceiveActivity アクティビティが WaitToStartService の子アクティビティとして既に設定されています。
receiveActivity1 を選択し、ServiceOperationInfo の [プロパティ] ウィンドウで省略記号をクリックして、[操作の選択] ダイアログ ボックスを開きます。
StartupService を選択して、[OK] をクリックします。
[プロパティ] ウィンドウで、CanCreateInstance の下のドロップダウン リストから True を選択します。これで、StartupService が呼び出されたときにワークフローのインスタンスが作成されます。このプロパティの既定値は False に設定されます。操作呼び出しの際にクライアントとサービスの間でコンテキスト ID が既に確立されていない場合は、クライアントが次のメッセージを受信します。
There is no context attached to incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized.
Workflow1InitialState のデザイン ビューで setStateActivity1 を選択します。
[プロパティ] ウィンドウで、TargetStateName プロパティの名前を stateActivity1 から OperationsState に変更します。
メイン ワークフローのデザイン ビューに戻ります。Workflow1InitialState と OperationsState が接続されていることを確認します。
5 つの EventDrivenActivity アクティビティを OperationsState StateActivity アクティビティにドラッグ アンド ドロップして、名前をそれぞれ WaitToAdd、WaitToSubtract、WaitToMultiply、WaitToDivide、および WaitToEndService に変更します。
WaitToAdd をダブルクリックして展開します。
ReceiveActivity アクティビティを WaitToAdd にドラッグ アンド ドロップします。
ServiceOperationInfo の [プロパティ] ウィンドウで、省略記号をクリックして [操作の選択] ダイアログ ボックスを開きます。
[追加] をクリックして [OK] をクリックします。
CodeActivity アクティビティを ReceiveActivity アクティビティにドラッグ アンド ドロップします。
[プロパティ] ウィンドウで [イベント] ボタンをクリックします。
ExecuteCode イベントのテキスト ボックスをダブルクリックして、ExecuteCode イベントのイベント ハンドラ メソッドを自動生成します。
Workflow1.cs (Visual Basic ソリューションを作成した場合は Workflow1.vb) を開いてクラスの名前を ServerWorkflow に変更し、テンプレートによって作成された returnValue および inputValue の変数宣言を次のように変更します。
Public class ServerWorkflow Inherits StateMachineWorkflowActivity Public returnValue As Int32 Public inputValue As Int32 Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) End Sub End Class
public sealed partial class ServerWorkflow : StateMachineWorkflowActivity { public ServerWorkflow() { InitializeComponent(); } public int returnValue = default(int);public int inputValue = default(int); private void codeActivity1_ExecuteCode(object sender, EventArgs e) { } }
ExecuteCode のイベント ハンドラに移動します。
イベント ハンドラの本体で、returnValue に以下の値を割り当てます。
Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue += inputValue End Sub
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { returnValue += inputValue; }
OperationsState のデザイン ビューに戻り、[ReceiveActivity アクティビティの追加] をクリックし、[プロパティ] ウィンドウで n1 と (ReturnValue) パラメータをそれぞれ強調表示して省略記号をクリックし、これらのパラメータをそれぞれ inputValue と returnValue にバインドします。プロパティのバインディング ダイアログ ボックスが開き、パラメータにバインドする適切なメンバを選択できます。
また、[プロパティ] ウィンドウで、CanCreateInstance を False に設定したままにして、手順 8. で作成したものと同じワークフロー インスタンスを引き続き使用するようにします。CanCreateInstance を True に設定すると、操作呼び出しごとに新しいワークフロー インスタンスが作成されます。
残りの各 EventDrivenActivity アクティビティに ReceiveActivity および CodeActivity アクティビティを追加します (WaitToSubtract から始めます)。また、操作パラメータをグローバル変数 inputValue および returnValue にバインドする必要もあります。
それぞれの算術演算に ReceiveActivity が関連付けられ、すべての CodeActivity アクティビティ イベント ハンドラが以下の方法で実装されたことを確認します。
Private Sub codeActivity1_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue += inputValue End Sub Private Sub codeActivity2_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue -= inputValue End Sub Private Sub codeActivity3_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue *= inputValue End Sub Private Sub codeActivity4_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) returnValue /= inputValue End Sub
private void codeActivity1_ExecuteCode(object sender, EventArgs e) { returnValue += inputValue; } private void codeActivity2_ExecuteCode(object sender, EventArgs e) { returnValue -= inputValue; } private void codeActivity3_ExecuteCode(object sender, EventArgs e) { returnValue *= inputValue; } private void codeActivity4_ExecuteCode(object sender, EventArgs e) { returnValue /= inputValue; }
WaitToEndService EventDrivenActivity アクティビティでは、ReceiveActivity アクティビティを WaitToEndService にドラッグ アンド ドロップします。
ServiceOperationInfo の [プロパティ] ウィンドウで、省略記号をクリックして [操作の選択] ダイアログ ボックスを開きます。
ShutdownService を選択して [OK] をクリックします。
OperationsState のデザイン ビューで、SetStateActivity を ReceiveActivity アクティビティの下の WaitToEndService にドラッグ アンド ドロップします。
SetStateActivity アクティビティを選択して、TargetStateName の [プロパティ] ウィンドウでドロップダウン リストから FinalState を選択します。
ワークフロー サービスを保持するには
App.config ファイルを開きます。
次のように、動作要素内の SqlWorkflowPersistenceService への参照を追加します。
<behavior name="WorkflowServiceTutorial.ServerWorkflowBehavior" > <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <serviceCredentials> <windowsAuthentication allowAnonymousLogons="false" includeWindowsGroups="true" /> </serviceCredentials> <workflowRuntime name="WorkflowServiceHostRuntime" validateOnCreate="true" enablePerformanceCounters="true"> <services> <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService, System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionString="Data Source=localhost\sqlexpress;Initial Catalog=NetFx35Samples_ServiceWorkflowStore;Integrated Security=True;Pooling=False" LoadIntervalSeconds="1" UnLoadOnIdle= "true" /> </services> </workflowRuntime> </behavior>
このチュートリアルで使用する SqlWorkflowPersistenceService は、ワークフロー専用のシナリオで使用する永続性サービスと同じ型です。つまり、ワークフロー インスタンスがアイドル状態のときにはいつでもワークフロー サービスの状態情報が SQL データベースに保持されるということです。このシナリオは、既定で .NET Framework Version 3.5 でサポートされていますが、WorkflowPersistenceService から派生させて、その他のデータベース ストアにデータを保持することもできます。
また、ワークフロー サービスでは Windows Workflow Foundation の永続性機能も使用できるため、ワークフロー サービスの状態情報は、永続性サービスなどの完了後ではなく、操作実装の実行中に保持されます。
PersistenceProviderElement の connectionString 属性値は "WorkflowServiceStore" に設定されます。これは、SQL データベースに接続を試行する際に使用される接続文字列の名前です。
メモ :
このチュートリアルでは、NetFx35Samples_ServicesWorkflowStore データベースを使用します。データベースを作成するには、「One-Time Setup Procedure for the Windows Communication Foundation Samples」の Createstores.cmd を実行します。 サービスをビルドして実行します。WcfSvcHost.exe が動作を開始し、サービスがホストされます。WcfSvcHost.exe は、テストの目的でサービスをホストする開発者用ツールです。テストの目的で、[シーケンシャル ワークフロー サービス ライブラリ] および [ステート マシンのワークフロー サービス ライブラリ] テンプレートが自動的に WcfSvcHost.exe アプリケーションを使用してワークフロー サービスをホストするため、ホスト アプリケーションを作成する必要はありません。
説明
ワークフロー サービスを作成した後は、このワークフロー サービスと対話できるワークフロー サービス クライアントを作成します。詳細については、「タスク 2: ワークフロー サービス クライアントの作成」を参照してください。
関連項目
タスク
概念
その他の技術情報
Copyright © 2007 by Microsoft Corporation. All rights reserved.