Workflow Foundationの特徴と概要
WFランタイムによるワークフローの実行
一般的な.NETアプリケーションとWFアプリケーションでは少々動作基盤が異なります。WFはWFランタイムと呼ばれる.NET共通言語ランタイム上に用意された環境の上で動作します。また、WFはWPFやWCFの技術も利用します。関係を簡単にまとめたものが下図になります。
アクティビティ(Activity)と呼ばれるものがWFにおける中心要素です。ワークフロー自体もアクティビティの一種ですし、ワークフロー上に配置するコンポーネントもアクティビティです。
アクティビティが実際に動作する基盤となるのがWFランタイムで、ワークフローの実行をコントロールし、実行時のスケジューリングやメタデータの管理、アクティビティ間の値の受け渡しなどを行います。
またワークフローデザイナー上で直接プロパティを設定できるようにするものを、アクティビティデザイナー(ActivityDesigner)と呼びます。この部分はWPFを利用しています。
作成されたワークフローを実行することを「ホスティングする」と呼びますが、そのための仕組みが3種類用意されています。
まずWorkflowInvokerクラスは最も簡単にワークフローを実行できます。その代わり、WFで提供される機能の中でも実行中に発生した例外などのイベント検知や入力の待機など、一部の機能が利用できないといった制限が設けられています。WorkflowApplicationクラスはすべての機能が利用できる標準のホスティング機能を有しています。
もう一つのWorkflowServiceHostクラスはすべての機能が利用できるという点でWorkflowApplicationクラスと同様ですが、Webサービスとして公開する機能を有している違いがあります。この部分ではWCFを利用しており、設定ファイルによるサービスの公開方法調整等はまったく同一です。
実際のホスティング方法は他にもInternet Information Service(IIS)上でのホスティングが行えます。さらにはIISの拡張機能を提供するWindows Server AppFabricにより、ワークフローの実行状況や保存状況等の監視・調整を行うことも可能です。
フロー形式によるコンポーネント指向開発
WFではロジックを直接記述する通常の形式による開発も行えますが、デザイナー上にドラッグ&ドロップを行い、xaml形式でファイルに保存することでも開発できます。Windows FormsやWPFで画面を作成する時に近い感覚で、必要なアクティビティコンポーネントをドラッグ&ドロップしプロパティの設定を行うことで、アプリケーションを作成できるようになっています。
作成したシーケンス型ワークフローをXAML形式で保存すると、次のように出力されます。
<Activity mc:Ignorable="sap" x:Class="Sequence1" sap:VirtualizedContainerService.HintSize="358,667" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Sequence DisplayName="シーケンス"> <Sequence.Variables> <Variable x:TypeArguments="x:Int32" Name="sumvalue" /> </Sequence.Variables> <sap:WorkflowViewStateService.ViewState> <scg:Dictionary x:TypeArguments="x:String, x:Object"> <x:Boolean x:Key="IsExpanded">True</x:Boolean> </scg:Dictionary> </sap:WorkflowViewStateService.ViewState> <WriteLine Text="処理を開始します" /> <ForEach x:TypeArguments="x:Int32" DisplayName="ForEach<Int32>" Values="[{1,2,3,4,5}]"> <ActivityAction x:TypeArguments="x:Int32"> <ActivityAction.Argument> <DelegateInArgument x:TypeArguments="x:Int32" Name="item" /> </ActivityAction.Argument> <Sequence> <sap:WorkflowViewStateService.ViewState> <scg:Dictionary x:TypeArguments="x:String, x:Object"> <x:Boolean x:Key="IsExpanded">True</x:Boolean> </scg:Dictionary> </sap:WorkflowViewStateService.ViewState> <Assign> <Assign.To> <OutArgument x:TypeArguments="x:Int32">[sumvalue]</OutArgument> </Assign.To> <Assign.Value> <InArgument x:TypeArguments="x:Int32">[sumvalue * item]</InArgument> </Assign.Value> </Assign> </Sequence> </ActivityAction> </ForEach> <WriteLine Text="["計算結果は " + sumvalue.tostring]" /> </Sequence> </Activity>
この出力結果はVisual Studioからではなく、Codeplex上で公開している拙作のツール(http://wfdesignerexpress.codeplex.com/)からであり、若干異なる部分はありますが、Visual Studioで作成した場合においてもほぼ同様の結果が出力されます。
このように非常にビジュアライズされた環境下で開発が行えるのは、WFの大きな特徴の一つです。見た目で処理イメージをつかみやすいこの形は、開発者だけではなくIT Proの方々にとっても、利用するための最初の一歩を踏み出しやすいのではないかと思います。このように部品単位で機能を用意し、必要に応じて組み合わせて利用する形式の開発を「コンポーネント指向開発」と呼ぶこともあります。