VS2008 のWFデザイナで ReceiveActivity の bool 型に対する動作が怪しい件

怪しい・・・実に怪しい・・・というかバグでしょ、これ?というのを見つけたのでご報告。
VS2008 のWF新機能で ReceiveActivity という WCFのサービスコントラクトを利用して、WFのワークフロー自身をサービスとして公開する機能のお話です。
バグの現象だけ書いてもつまらないので、WFサービス作成の手順に沿って説明することにしましょう。VS2008 をまだ触ったこと無い方は WFサービスの作り方をイメージして読んでみてください。
ちなみに、WF サービスって何という話ですが、VS2005 で WCFサービス上に WF をホストしたい場合、WCF のサービス実装内に WFのランタイムの実装をゴリゴリ記述する


【はじめに】
まずは、VS2008 でWFサービスのプロジェクトを作成してみましょう。VS2008 を起動し、新しいプロジェクトの作成で「プロジェクトの種類:WCF」、テンプレートを「シーケンシャルワークフローサービスライブラリ」か、「ステートマシンワークフローのサービスライブラリ」を選択します。ここではシーケンシャルワークフローでいくことにしましょうか。



WCFのサービスコンストラクタであるインターフェイス定義(IWorkflow.cs)とそれを利用したシーケンシャルワークフロー(Workflow1.cs)が作成されます。



【int 型を引数に使用した場合(正しい動作)】
ここまではプロジェクト作成の流れです。まずは本来の正しい動作をみてみましょう。まずはデフォルトで作成されるサービスコンストラクタから。



int 型の引数を1個渡し、文字列の戻り値を受け取るだけの単純な例ですね。WFサービスでは、このサービスコンストラクタをワークフロー定義の中の ReceiveActivity から参照する形になります。



ServiceOperationInfo のプロパティで先ほどのサービスコンストラクタ(WFServiceLibrary.IWorkflow1.GetData)を参照していることがわかります。また、int 型引数(value)と文字列型戻り値(ReturnValue)がそれぞれワークフロー内のプロパティとバインドされていることもわかります。つまりこのWFサービスが呼び出されたら、この ReceiveActivity が実行され、渡された引数がワークフロー内のプロパティの値に自動的に設定されるようになります。
# ReceiveActivity の CanCreateInstance プロパティが true に設定されていることもポイントの1つです。ここが true に設定されていることで、このサービスが呼び出されるたびにワークフローインスタンスが自動的に作成されるようになります。

そのまま実行できますのでデバッグ実行してみましょう。



VS2008 では、WCFサービスライブラリのプロジェクトを実行すると「WCF サービスホスト」というホストプログラムが起動し、サービスを外部からつつける状態になります。ま、これが毎回デバッグ時に立ち上がってくるのでウザイ時もありますが(停める手段が無さそうなんですよね...これ)。



WCF サービスホストが起動するのと一緒に「WCFテストクライアント」なるものも VS2008 では起動します。これは WCF のテストを行うことができるクライアントアプリですね。なにしろ、VS2005 の時は何にも無かったのでこれはテストしやすくなっていて素直にですね。



WCFテストクライアントの簡単な使い方ですが、左側のサービス内のメソッド名をダブルクリックすると右側のタブにメソッドの引数入力のペインが表示されます。引数の値を指定し「起動」ボタンをクリックするとサービスを呼び出すことができます。
ここでは、value 引数に 0 の値を渡し、 GetData() メソッドを実行して、戻り値の null が返ってきたことを確認した例ですね。こんな感じで WCF サービスの呼び出しに成功しました。


...で、問題はここから。


【bool 型を引数を使用した場合(バグ?)】
先ほどは int 型引数を使用していましたが、今度は bool 型に変更してみます。



サービスコンストラクタの定義で int 型引数から bool 型引数へ書き換えます。ついでに引数名も boolValue とか適当な名前に変えてみました。



するとワークフローの ReceiveActivity でも bool 型引数に変わっています。じゃあ、この引数とワークフローのプロパティとのバインドの設定を・・・



できない!!
true/falseって・・・ここで値を指定って、静的な値を割り当ててどうする??
(@_@;)

【困ったので力づくで修正してみました】
残念ながらデザイナの設定でここをなおす手段はなさげです。ちょっと強引ですが、ワークフローデザイナの生成コードを手動で修正してみます。まずはWorkflow1.Designer.cs を開きます。



引数に関係するコードは上ですね。ここを・・・



このように書き換えちゃいます。バインド先の BoolValue プロパティは手書きで追加。



書き換えが上手くいけばデザイナにも正しく表示できますし、ReceiveActivity のプロパティからも変更できるようになりますね。ついでに実行してみましょう。



WCF テストクライアントからも問題なくで動きました。スクリーンショットは載せてませんが、WF にブレイクポイントを設定しデバッグ実行すると WCF テストクライアントから渡された bool 型引数の値がワークフローの BoolValue プロパティに設定されることが確認できます。
また、今回はコードを使用しましたが XOML (コード分離付きワークフロー)を使用している場合でも現象と対処方法は同じです。

きっとバグですね、これ。英語記事でも同様の現象の記述をみつけましたし(↓)。


Bugs, Workarounds, And Gotchas in VS 2008
http://visualstudiomagazine.com/columns/article.aspx?editorialsid=2423


長くなりましたが・・・というわけで、VS 2008 で WF を使う方はご注意を ;-)