SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Workflow Foundation 4が導く新しい開発スタイル

非常に簡単! 自作アプリでのワークフローデザイナー利用

Workflow Foundation 4が導く新しい開発スタイル(3)

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード WF4_3_VB.zip (38.6 KB)
ダウンロード WF4_3_CS.zip (28.3 KB)

ワークフローの検証と実行

 最後に作成したワークフローを実行する機能を記述します。実際に作成したワークフローの実行に必須ではありませんが、事前にワークフローの検証を行っておくべきかと思います。設定誤りなどが存在する状態でワークフローを実行した場合は例外が発生しますので、それを防ぐ意味合いでも事前の検証は有効です。

 編集しているワークフローでは何かしらのエラーがあるアクティビティに対して、赤い「!」マークが表示されるようになっています。ただしあくまでもこの表示はデザイナ上だけであり、アプリケーション側ではそのままですと検知できません。発生しているエラーすべてを検知するにはActivityValidationServicesクラスを利用します。

サンプルコード(Visual Basic)
Dim resultID As String = ""
Dim rootActivity As Activity = Nothing
'現在のワークフロー情報を取得
Dim mdlService = designer.Context.Services.GetService(Of ModelService)()
Dim debugTree = TryCast(mdlService.Root.GetCurrentValue(), IDebuggableWorkflowTree)
If (debugTree IsNot Nothing) Then
  rootActivity = debugTree.GetWorkflowRoot()
Else
  rootActivity = mdlService.Root.GetCurrentValue()
End If
‘ワークフローの検証実施
Dim validError = ActivityValidationServices.Validate(rootActivity)
‘検知したエラーが発生している先頭のアクティビティIDを取得
If validError.Errors.Count > 0 Then
  resultID = validError.Errors(validError.Errors.Count - 1).Id
End If
サンプルコード(C#)
var resultID = "";
Activity rootActivity = null;
//現在のワークフロー情報を取得
var mdlService = designer.Context.Services.GetService();
var debugTree = (IDebuggableWorkflowTree)mdlService.Root.GetCurrentValue();
 if (debugTree != null) {
   rootActivity = debugTree.GetWorkflowRoot(); 
} else {
     rootActivity = (Activity)mdlService.Root.GetCurrentValue(); 
} 
//ワークフローの検証実施 
var validError = ActivityValidationServices.Validate(rootActivity); 
//検知したエラーが発生している先頭のアクティビティIDを取得 
if (validError.Errors.Count > 0) {
   resultID = validError.Errors(validError.Errors.Count - 1).Id; 
} 

 ActivityValidationServicesクラスを利用してワークフローの検証を行う際には、対象となるワークフローの構造情報が必要です。それを行っているのがModelServiceクラスを利用している前半の部分となります。後半部分は、前半で取得した構造情報をもとにActivityValidationServicesによる検証を行っています。検証結果はValidationResultsコレクションで返却され、発生しているすべてのエラー情報が収納されています。この内容を用いて、発生しているエラー情報を一覧にして表示するといったことが可能です。

 なお、WorkflowDesigner.IsInErroStateプロパティという、エラーが発生しているかどうか判断できそうなプロパティがありますが、残念ながら思うように動作していないので利用することができません。

ValidationServiceで行われる検証

 検証に利用するもう一つのサービスとしてValidationServiceがあります。こちらはActivityValidationServicesと異なり、ワークフローデザイナー上で編集しているワークフローの検証を行うためのサービスで、検証結果を取得するなどは行えません。どのような場面で利用するかというと、ワークフローデザイナーにワークフローを読み込ませた直後やプログラム側でワークフローを操作した直後などであり、ワークフローデザイナー以外からワークフローを操作した場合に明示的に検証を行い、ワークフローデザイナーに反映させるためのものとなっています。

 

ValidationServiceを利用していない場合
サンプルコードの実行結果

 ワークフローデザイナーに読み込ませたまでの状態では上図のとおりになります。エラー表示が行われていないのが確認できます。

 

ValidationServiceを利用した場合
サンプルコードの実行結果

 こちらがワークフローデザイナーに読み込ませた後にValidationServiceを利用して検証を行った状態です。アクティビティの右上に「!」と赤くエラー表示されているのが確認できます。この時のコードは次のようになっています。

サンプルコード(Visual Basic)
Dim meta = New DesignerMetadata
meta.Register()
Dim designer = New WorkflowDesigner
Dim seq = New Sequence
seq.Activities.Add(New Assign())
designer.Load(New ActivityBuilder With {.Implementation = seq})
'ValidationService による検証
Dim vsv = designer.Context.Services.GetService(Of ValidationService)()
vsv.ValidateWorkflow()
Content = designer.View
サンプルコード(C#)
var meta = new DesignerMetadata();
meta.Register();

var designer = new WorkflowDesigner();
var seq = new Sequence();
seq.Activities.Add(new Assign());
designer.Load(new ActivityBuilder {Implementation = seq});
//ValidationService による検証
var vsv = designer.Context.Services.GetService();
vsv.ValidateWorkflow();
Content = designer.View; 

 検証が終われば次は実行です。ワークフローデザイナーを利用して編集したものを実行する方法はいろいろな種類がありますが、ここでは最も簡単に行う方法として、ワークフローを一度保存しそれを実行する方法を紹介します。

サンプルコード(Visual Basic)
‘ワークフローの保存
wfDesign.Save("test.xaml")
'保存したワークフローの取得
Dim wfFile = ActivityXamlServices.Load("test.xaml")
'保存したワークフローをメタデータに取り込み
WorkflowInspectionServices.CacheMetadata(wfFile)
Dim wfInv As New WorkflowInvoker(wfFile)
wfInv.Invoke()
サンプルコード(C#)
//適当なファイルに保存
wfDesign.Save("d:\test.xaml");
//保存したファイルよりワークフローを読み込み
var wfFile = ActivityXamlServices.Load("d:\test.xaml");
//読み込んだワークフローのメタデータを登録
WorkflowInspectionServices.CacheMetadata(wfFile);
//ワークフローの実行
var wfInv = new WorkflowInvoker(wfFile);
wfInv.Invoke();

 WorkflowDesigner.Saveメソッドや前述した方法を用いて、xamlファイルとしてワークフローを保存します。保存したワークフローをActivityXamlServicesクラスのLoadメソッドを用いて読み込ませ、WorkflowInspectionServices.CacheMetadataメソッドでメタデータへ登録を行います。そうすることでWorkflowInvokerクラスなどを利用し、ワークフローの実行を行うことができます。

まとめ

 WF4では標準提供されるWorkflowDesignerクラスやToolboxControlを利用することで、非常に簡易にワークフローデザイナーの機能を利用することが可能です。実行、保存、検証など、ワークフローアプリケーションに必要な機能も多くのクラスが提供されており、Visual Studio環境と同等のものを作成することができます。

次回予定

 次回はWF4を利用するのに適しているケースをもとに、利用例を紹介する予定です。どのような場面がWF4の特性を生かしやすいのか、またWF技術のこれからについて紹介させていただく予定です。

参考資料

修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Workflow Foundation 4が導く新しい開発スタイル連載記事一覧

もっと読む

この記事の著者

小尾 智之(オビ トモユキ)

地方企業に勤めるインディープロレス好きなエンジニア。VB + SQL Server のシステム構築を主な業務としていましたが、元々の性格もあり色々な物に目移り中。Ahf というハンドルネームで所属する北海道の技術コミュニティ CLR/H(http://clr-h.jp) での活動など行っていましたが、最近か...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6729 2012/08/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング