CodeZine(コードジン)

特集ページ一覧

Visual Studio 2008で標準搭載されたWindows Workflow Foundation

Visual Studio 2008 徹底入門 (8)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/05/09 00:00
目次

サンプル1~シーケンシャル ワークフロー

 では、早速ワークフローを使ったサンプルを実装してみましょう。最初はシンプルなシーケンシャル ワークフローをデザインし、スタンドアロンアプリケーションでホスティングします。

 今回は購入申請アプリケーションで、入力された申請内容の条件を見て、申請を許可するか却下するかを判断する、というワークフローを作成します。

 申請内容は次のようなクラスで、金額・申請者名・申請品目のみを保持するものとしましょう。

申請クラス ApplicationForm.cs
public class ApplicationForm
{
  int price;

  public int Price //金額
    {
      get { return price; }
      set { price = value; }
    }

  string applicantName;
  public string ApplicantName //申請者名
    {
      get { return applicantName; }
      set { applicantName = value; }
    }

  string productName;
  public string ProductName //購入品目
    {
      get { return productName; }
      set { productName = value; }
    }
}

 このクラスのPriceプロパティが一定額未満であれば購入許可、一定額以上であれば拒否、というシンプルなワークフローです。

 [ファイル]-[新規作成]-[プロジェクト]を選択し、[Visual C#]-[Workflow]-[シーケンシャル ワークフロー コンソール アプリケーション]を選択してプロジェクトを作成します。

 ここではSeqWFTestというプロジェクトを作成しました。

プロジェクトの作成
プロジェクトの作成

 プロジェクト作成後、ワークフローのひな形としてWorkflow1.csが作成され、デザイン画面が表示されます。

ワークフローのデザイン画面
ワークフローのデザイン画面

 シーケンシャル ワークフローは前述の通り、ワークフロー開始から終了までアクティビティが順に実行されて流れていくワークフローです。この画面のがワークフロー開始を、がワークフロー終了を表しています。

 では、ワークフローをデザインしてみましょう。

アクティビティの配置

 まずツールボックスからIfElseアクティビティをドラッグ&ドロップでワークフロー開始と終了の間に貼り付けます。

IfElseアクティビティ配置
IfElseアクティビティ配置

 IfElseアクティビティは、前述の通りコンポジット アクティビティで、条件分岐した後に実行すべきアクティビティを持つことができます。今回はプログラムを直接実行するCodeアクティビティをそれぞれに配置してみましょう。

Codeアクティビティ配置
Codeアクティビティ配置

 以上でアクティビティの配置は完了です。次に条件とコードの実装に進んでいきましょう。

ワークフローのパラメータ指定

 条件分岐の設定をする前に、[プロジェクト]-[新しい項目の追加]から[クラス]を選択し、先ほどのApplicationFormクラスをプロジェクトに追加しましょう。

 次にワークフローに、パラメータである購入申請を受け取るためのプロパティを追加します。

 ソリューション エクスプローラの「Workflow1.cs」を右クリックし、[コードの表示]を選択して、以下のコードを追加します。

プロパティ追加
private ApplicationForm form;

public ApplicationForm Form
{
  get { return form; }
  set { form = value; }
}

IfElseアクティビティの条件設定

 次に条件設定です。貼り付けたIfElseアクティビティの左下のifElseBranchActivity1をクリックし、右下のプロパティペインでConditionプロパティを設定します。

Conditionプロパティの選択
Conditionプロパティの選択

 ソースコードによる条件指定も可能ですが、今回は[宣言型のルール条件]を選択しましょう。Conditionプロパティの配下にConditionNameプロパティが作成されますので、右端の[...]ボタンをクリックします。

 [条件の選択]画面で[新規作成(N)]ボタンをクリックします。

[条件の選択]画面
[条件の選択]画面

 [ルール条件エディタ]画面で実際の条件を指定します。

 入力された購入申請の価格が5000未満かどうかという条件分岐にしますので、

form.Price < 5000

 という条件を入力します。入力の際に、IntelliSenseが働くことに注目してください。

 [OK]ボタンを押し、[条件の選択]画面で条件を確認してください。

追加された分岐条件
追加された分岐条件

Codeアクティビティへのコード実装

 以上で条件分岐が設定できたので、Codeアクティビティで条件分岐後のコードを書きましょう。Codeアクティビティをダブルクリックすると、実行するコードを記述するためのハンドラが自動生成されます。

 ここでは次のようにハンドラを記述します。

Codeアクティビティのハンドラ記述
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
  //条件真の場合
  Console.WriteLine(
    string.Format("{0}さんの{1}購入申請は許可されました。",
    form.ApplicantName, form.ProductName));
}

private void codeActivity2_ExecuteCode(object sender, EventArgs e)
{
  //条件偽の場合
  Console.WriteLine(string.Format(
    "{0}さんの{1}購入申請は却下されました。", form.ApplicantName,
    form.ProductName));
}

 条件を満たす場合、満たさない場合それぞれにメッセージを出力します。

 以上でワークフロー側の実装は完了です。

Mainメソッドからのワークフロー呼び出し

 次に「Program.cs」を開き、Mainメソッドの内容を確認しましょう。

Program.cs
static void Main(string[] args)
{
  using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
  {
    AutoResetEvent waitHandle = new AutoResetEvent(false);
    workflowRuntime.WorkflowCompleted +=
      delegate(object sender, WorkflowCompletedEventArgs e)
      {waitHandle.Set();};
    workflowRuntime.WorkflowTerminated +=
      delegate(object sender, WorkflowTerminatedEventArgs e)
    {
      Console.WriteLine(e.Exception.Message);
      waitHandle.Set();
    };

    WorkflowInstance instance =
      workflowRuntime.CreateWorkflow(typeof(SeqWFTest.Workflow1));
    instance.Start();

    waitHandle.WaitOne();
  }
}

 ここで重要なのはワークフローの生成を司るWorkflowRuntimeクラスと、ワークフローの実体を表すWorkflowInstanceクラスです。

 WorkflowRuntimeクラスはワークフローを実行するためのランタイムで、1つのプロセスに付き1つだけインスタンスを生成し、その上でワークフローを実行します。

 続いていくつかのイベントハンドラ登録を行った後、WorkflowRuntime#createWorkflowメソッドからWorkflowInstanceインスタンスを生成しています。引数にSeqWFTest.Workflow1クラスの型を指定することで、実際に実行するワークフローを特定します。その後Startメソッドで実行を開始します。

 以上はワークフロー実行時にパラメータを渡さない場合のコードです。今回は購入申請をパラメータとして渡しますので、コードの書き換えを行いましょう。

 CreateWorkflowメソッドでインスタンス生成を行っている部分を、次のように書き換えます。

ワークフローへのパラメータ指定
//購入申請インスタンス生成
ApplicationForm form = new ApplicationForm();
form.ApplicantName = "土井";
form.Price = 3200;
form.ProductName = "参考文献";

//パラメータとなるDictionaryクラスを生成
Dictionary<string, object> properties =
  new Dictionary<string, object>();
properties.Add("Form", form);

//ワークフロー生成時にパラメータも渡す
WorkflowInstance instance = workflowRuntime.CreateWorkflow(
  typeof(SeqWFTest.Workflow1),properties);
instance.Start();
waitHandle.WaitOne();
Console.ReadKey(); //キー入力待ち

 ApplicationFormクラスに申請情報を入力し、それをDictionary型のproperties変数にいったん格納します。その際にキーとして指定した文字列"Form"は、ワークフローに作成したプロパティ名と合わせる必要があります。パラメータを詰めたproperties変数をCreateWorkflowメソッドの2番目の引数として指定します。ここで、内部的にはDictionary型のキーと値が、ワークフローのプロパティ名とプロパティ値とみなされ、プロパティが設定されます。

 この場合は作成した申請情報がFormプロパティに設定された上でワークフローが生成されることになります。

ワークフローの実行

 では、[F5]キーを押して実行してみましょう。

 今回はPriceプロパティの値が3200ですので、条件(Priceが5000未満)を満たし、購入申請は許可されます。

実行結果
実行結果

 ワークフローのデザイン/実行が非常にシンプルなことがご理解いただけたかと思います。

 

  • LINEで送る
  • このエントリーをはてなブックマークに追加

あなたにオススメ

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 土井 毅(ドイ ツヨシ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

バックナンバー

連載:Visual Studio 2008徹底入門

もっと読む

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5