第二歩~IfElseアクティビティ
では次に、IfElseアクティビティを使って条件分岐を行ってみましょう。
IfElseアクティビティは条件としてソースコードを指定することもできますが、ルール条件を指定して分岐を行うこともできます。
最初に上げた購入申請のフローの一部を作ってみましょう。ワークフロー外部からワークフローに情報を渡す必要がありますので、その受け渡しについても確認しましょう。
以下の手順で作業を進めます。
- 申請情報・申請者情報をワークフロー外部で定義する
- 申請クラスのインスタンスをワークフローに渡す
- ワークフロー内で、外部から渡された申請インスタンスに対して条件判断をする
まず、申請クラスと申請者クラスを「Program.cs」内に次のように定義します。
申請クラスは申請者・今回の申請額を、申請者クラスは名前とその人が上長承認無しに決裁可能な裁量金額を持ちます。
//申請クラス public class Application { //申請者 private Employee applicant; //申請額 private int price; public Employee Applicant { get { return applicant; } set { applicant = value; } } public int Price { get { return price; } set { price = value; } } } //社員クラス public class Employee { //申請者氏名 private String name; //裁量金額 private int maxPrice; public String Name { get { return name; } set { name = value; } } public int MaxPrice { get { return maxPrice; } set { maxPrice = value; } } }
次に、ワークフローにこの申請インスタンスを受け取るためのプロパティを追加します。「Workflo1.cs」に以下のコードを追加します。
private Application applicationParameter; public Application ApplicationParameter { get { return applicationParameter; } set { applicationParameter = value; } }
ワークフロー実行時にApplicationインスタンスを渡すようにしましょう。「Program.cs」のMain
メソッドを次のように書き換えます。
//ワークフローに与えるDictionaryインスタンス Dictionary<string, object> properties = new Dictionary<string, object>(); //申請者インスタンス Employee person = new Employee(); person.Name = "Doi"; person.MaxPrice = 1000; //裁量金額は1000円まで //申請インスタンス Application application = new Application(); application.Applicant = person; application.Price = 2000; //裁量以上の金額を申請 //Dictionaryに申請インスタンスを追加 properties.Add("ApplicationParameter", application); //CreateWorkflow時にDictionaryインスタンスを指定 WorkflowInstance instance = workflowRuntime.CreateWorkflow( typeof(WFSequenceSample.Workflow1),properties); instance.Start();
このように、申請インスタンスをCreateWorkflow
メソッドに渡すことで、ワークフローに対してパラメータを渡すことができます。ワークフロー側のプロパティ名と、CreateWorkflow
に渡すDictionary
インスタンスに格納するキーが同じ"ApplicationParameter"であることに注目してください。こうすることでCreateWorkflow
メソッドが自動的に同名のプロパティにインスタンスを紐づけてくれます。
このように、WFでは、起動時のパラメータやWebサービスの取得結果などをプロパティで受け渡しします。
では、Codeアクティビティを削除し、IfElseアクティビティをドラッグ&ドロップで配置しましょう。
左下のifElseBranchActivity1をクリックし、プロパティペインの"Condition"を[宣言型のルール条件]に、"ConditionName"を"isUnderMaxPrice"に設定し、"Expression"に以下の条件を入れてください。
this.Application.Price > this.Application.Applicant.MaxPrice
「Program.cs」から渡された申請インスタンスをプロパティから取得し、申請金額と裁量金額を比較する条件を入れています。この条件が真であればマネージャの決裁が必要、偽であればそのまま購入許可が出る、ということになります。
何の気無しにファイルの中身を覗いて思わず絶句。条件式がきちんとXML化されています。
<RuleExpressionCondition Name="isUnderMaxPrice"> <RuleExpressionCondition.Expression> <ns0:CodeBinaryOperatorExpression Operator="GreaterThan" xmlns:ns0="clr-namespace:System.CodeDom;Assembly=System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <ns0:CodeBinaryOperatorExpression.Left> <ns0:CodePropertyReferenceExpression PropertyName="Price"> <ns0:CodePropertyReferenceExpression.TargetObject> <ns0:CodePropertyReferenceExpression PropertyName="ApplicationParameter"> <ns0:CodePropertyReferenceExpression.TargetObject> <ns0:CodeThisReferenceExpression /> </ns0:CodePropertyReferenceExpression.TargetObject> </ns0:CodePropertyReferenceExpression> </ns0:CodePropertyReferenceExpression.TargetObject> </ns0:CodePropertyReferenceExpression> </ns0:CodeBinaryOperatorExpression.Left> ・・・省略・・・
Codeアクティビティで分岐結果を書きましょう。Codeアクティビティを分岐の左下(上のルール条件が真の場合)と右下(偽の場合)にドラッグ&ドロップし、それぞれコードを書きます。
private void codeActivity1_ExecuteCode_1(object sender, EventArgs e) { //ルール条件真の場合 Console.WriteLine("要マネージャ決裁"); } private void codeActivity2_ExecuteCode(object sender, EventArgs e) { //ルール条件偽の場合 Console.WriteLine("購入許可"); }
[F5]キーを押して実行しましょう。
社員の裁量金額を超えた申請のため、指定したルール条件が真となり(ワークフローが左側に流れ)、"要マネージャ決裁"というメッセージがコンソールに出力されるはずです。
このように、IfElseアクティビティを使うことで条件分岐をコード内に埋め込んでしまうのではなく、プロパティとしてワークフロー内で設定できます。こうした条件による処理は、ConditionedActivityGroupアクティビティやWhileアクティビティでも使うケースですので、よく理解しておきましょう。
まとめ
前編では、ワークフローの概要・WFの特徴・シーケンシャルワークフローのサンプルについて扱いました。また、ワークフローに必要な分岐処理や外部からのパラメータの渡し方などを説明しました。WFが提供しているさまざまなアクティビティを使うことで、業務に必要なワークフローを構築していくことができるでしょう。
次回はステートマシンワークフローによるサンプルを取り上げます。シーケンシャルワークフローとは異なるモデルですので、また頭を切り換えて取り組みましょう。
それでは、次回もお楽しみに。
参考資料
- Microsoft Windows Workflow Foundation 入門: 開発者向けの手引き
- ディベロッパー製品開発統括部 Blog