Uncategorized

Microsoft Office SharePoint Server (MOSS) 2007 ワークフローの解剖学

こんにちは。

以前、Web ページ (ASP.NET ページ) の画面遷移を WF で実装する場合の例について記載しましたが(こちら)、今回は WF を使った実践的アプリケーションの1つとして、SharePoint のワークフローの世界をみていきましょう。

WF (Windows Workflow Foundation) は、ワークフロー的な動きをシステムで実現するためのベースのフレームワークエンジンです。SharePoint もそうしたエンジンを使った実践的サンプルプロダクトの 1 つとしてとらえることができます。
SahrePoint のワークフローをご存知の方にとっては既知の情報かもしれませんが、WF を理解されていて「SharePoint はちょっと知らないんだよね」という方は、みなさんのシステム実装のヒントとして是非お役立てください。

前回の画面遷移の説明と同様、このポストを理解するには、WF の性質に関する基本的な性質の理解が必要です。WF とはどのようなもので、どんな風に機能を実現していくかという点について理解してもらうため 「ワークフローの作成とランタイムサービス (EDS, 永続化サービス) の利用」 でデモをおこなっていますので、まだ WF はこれからという方は、是非参考にしてください。(50分と長いので、我慢できない方は全画面表示にして再生速度を早くしてご視聴ください。このポストに限らず、EDS、永続化サービスなどについては実際のWFによる開発では必ず必要になりますので、是非理解しておいてください。)

さて、SharePoint のワークフローですが、その実態は、組み込みのランタイムサービスやカスタムサービス、さらにそれらを利用したカスタムアクティビティなどを組み合わせて作られた WF アプリケーションに他なりません。SharePoint の場合、ホストスレッドは w3wp.exe 上で動いている ASP.NET フレームワーク上のスレッドであり、このスレッドとワークフローインスタンスのスレッド間の連携は、WF ではお馴染みのデータ交換サービス (EDS) が使用されます。

SharePoint ワークフローのデザイナー上で利用できる CreateTask アクティビティや CompleteTask、SetState アクティビティさらには SendEmail アクティビティに至るまで、ワークフローインスタンス側から処理を要求する概ねのアクティビティは、データ交換サービスで使用される CallExternalMethod アクティビティが継承されたものです。(「概ね」と書いた理由は、LogToHistoryListActivity アクティビティなど、ごく一部のもののみ異なるためです。) これらは、SharePoint の世界では Action Activity と呼ばれています。
となれば、もう当然おわかりと思いますが、今度は SharePoint のホストスレッドからワークフローインスタンス上の別スレッドに対してイベント処理をおこなう OnWorkflowActivated アクティビティや OnTaskChanged アクティビティなどなどの On ではじまる類のものは、HandleExternalEvent アクティビティが継承されているわけですね。こっちのほうは、一般に、Event Activity と言われます。

Event Activity には、ワークフローに対するイベントのもの、タスクに対するもの、アイテムに対するものなどが存在しています。これらはすべて別々のデータ交換用のインタフェース (つまり、データ交換サービスで一般に使用する、ExternalDataExchange 属性が指定された専用インタフェースです) が設定されています。
例えば、OnItemChanged アクティビティで使用するアイテムのライフサイクルに関しては、Microsoft.SharePoint.Workflow 名前空間の IListItemService インタフェースというものが使用され  (← 2007/07/04 訂正:すみません、記述が正しくありません。Microsoft.SharePoint.WorkflowAction に OnItemChanged アクティビティは含まれていませんので、正確には、IListItemService の OnItemChanged イベントを使って開発者自身が同等のアクティビティをカスタムに作成する必要があります。方法については、TechED などでご紹介していきます)、SharePoint のホストスレッド側でこの実装が設定されています。(MSDN のリファレンスをみるか、Microsoft.SharePoint.dll を逆アセンブルすることで、どのようなインタフェースがあり、どのようなメソッドが利用可能か参照できます。)

ですから、例えば、独自に HandleExternalEvent アクティビティを継承して、HandleExternalEvent の InterfaceType プロパティと Method プロパティにこれらの公開されているインタフェースとメソッドを指定することで、まったく独自の SharePoint で提供されているものと同等なアクティビティを簡単に作成することができるわけです。(ECM Starter Kit (および SharePoint SDK) に付属のサンプルコードには、こうしたサンプルも存在しています。) 無論、Action Activity (インスタンススレッド → ホストスレッド) についても同様です。
ただし、逆の言い方をすると、この方法からはずれた連携方法は標準の手法ではできない (もしくはバージョンアップなどに対してサポートされない) と思ってください。例えば、1つのワークフローから別のドキュメントライブラリのアイテムとイベントドリブンに連携したいと思っても、標準的な仕組みでは不可能ということです (イベントレシーバーを使った強引な実装など、かなりまわりくどい実装になることでしょう)。ですから、こうした場合には、SharePoint ワークフローの実行の途中で適宜複数のドキュメントライブラリやリストとキャッチボールをするのではなく、例えば、そのワークフローでは必要な属性を (InfoPath のフォームなどで) すべて設定させてから、最後に、Code アクティビティやカスタムアクティビティなどで必要な他のドキュメントライブラリなどにドキュメント生成をおこない、そこで作成されたドキュメントにはまた意味的に別なワークフローを作成するというモデルで構築するなど、フレームワークにあったモデルで構築することになります。(例えば、「受注処理」のワークフローには「受注データ」を保管するドキュメントライブラリと関連させて連携し、その途中で連携すべき「製造受付」のワークフローがあるならば「製造指示書」を登録し、その「製造指示書」のドキュメントライブラリとインタラクティブに動作する別の意味の「製造受付」ワークフローを呼び出すという段取りです。「受注処理」の途中で「製造受付」と関連するデータが必要であっても、あくまでも「受注処理」で扱うデータの1つとして管理し、必要なタイミングでこのデータを使用して「製造指示書」を作成するといった具合です。SharePoint 自体には、残念ながら、ワークフロー間のオーケストレーションの仕組みは備わっていません。)

長くなってしまいましたが、永続化サービス、トラッキングなどについても同様に、標準的な仕組みを使用しています。
一般のカスタムな永続化サービスを作成する際に使用する WorkflowPersistenceService (抽象クラス) を継承して、 SharePoint 専用の SPWinOePersistenceService という専用の永続化サービスが使われています。

ブログにしては長すぎたのでこの辺でやめておきますが、要は、SharePoint Designer で扱われるアクティビティを除いては、WF のごくごく一般的なフレームワークが使用されているため、WF の範囲で可能なあらゆるカスタマイズが可能になっているという点が重要です。
ただし、WF で提供されている標準アクティビティのうち、使えるアクティビティは限られていますので注意してください。Replicator アクティビティなどはそのまま使えますので、「複数へのアサインの実施」といった処理などでも大活躍することでしょう。

今後は、セミナーなどでも、「SharePointとは何か」ではなく、より実践的な手法(実践アプリを意識した内容)や考え方をご紹介していきたいと思います。

Categories: Uncategorized

Tagged as: ,

Leave a Reply