2015年2月1日日曜日

InvokeDelegate アクティビティで「処理」を受け取る

元々存在していたアクティビティの中で、ここまでに取り上げてこなかったものの一つに InvokeDelegate アクティビティがあります。名前からもわかる通り、このアクティビティは、Delegate を Invoke する、つまり受け取った Delegate を呼び出すことができるものです。

Delegate を受け渡すのは、コード上でやる分にはなんてことのない話なのですが、ワークフローデザイナー上でやろうとすると、難易度がどうしてもアップするというかあまり良いやり方が見つかっていません。

MSDN にサンプルがあるので、これを元に説明します。

image

InvokeDelegate アクティビティを用いた「カスタムアクティビティ」のサンプルになります。ワークフロー本体ではなく、カスタムアクティビティというところに注意してください。続いてこのカスタムアクティビティで利用する変数定義です。

image

このカスタムアクティビティは、受け取った処理を全て実行するもので、そのカウンタとなる変数を定義しています。

image

次にカスタムアクティビティとして受け取る「引数」を定義します。ここで定義した引数は、カスタムアクティビティ自体のプロパティとして外部からアクセスできるのですが、今回は Body という変数を「プロパティ」として定義している点に注意が必要です。

プロパティとして定義した場合、カスタムアクティビティのプロパティとなりますので、内部で利用しているアクティビティ群からはアクセスできません。何故プロパティを利用しているかについては、もう少し調査が必要なところです。

そしてもう一つ、この Body と言う引数の型も注意が必要です。ActivityAction<Object> を指定していて、アクティビティの処理を受け取ることができるようになります。

この状態で一度ビルドすることで、このカスタムアクティビティを利用することができます。

image

CustomDelegate としている部分が先ほど作成したカスタムアクティビティです。

image

元々存在する DiaplyName はさておき、カスタムアクティビティの実装で引数に設定したものが追加されています。Items にはカスタムアクティビティに引き渡す値を設定していますが、もう一つの Body には ActivityAction’1 と表示されています。これは、カスタムアクティビティにアクティビティを追加、今回の例でいうと WriteLine アクティビティを追加した際に自動で設定されます。ここの記述によって、カスタムアクティビティに設定されたアクティビティ自身が「処理」として、カスタムアクティビティに伝わる仕組みとなります。

ここで?と思われるのは、親元のワークフロー上では Argument というのが使われていますが、ここまでにそれらしい記述はでてきていません。実際にはこの Argument はカスタムアクティビティの InvokeDelegate アクティビティにて設定したものとなります。

image

InvokeDelegate アクティビティのプロパティをみると、DelegateArguments というプロパティがあります。この設定ボタンをクリックすると次の画面が表示されます。

image

ここでようやく先程ワークフローで利用した Argument が登場します。ここで指定するのは、Argument としてワークフローから受け取る値についてとなります。今回でいうと、Argument には New Object(){1, “ABC”, “TEST”} という配列がわたってきます。これらをループの中で InvokeDelegate で処理するのですが、その際に利用したい値は、受け渡された Object 配列の 1 要素です。それを設定しているのが値の部分で、Items(Index).ToString がそれにあたります。

こうすることで、ワークフロー側で指定した処理 WriteLine がカスタムアクティビティ内部で呼び出されて実行することができるようになります。使いどころが難しいですが、利用できるとワークフローの幅を広げることも可能なのかな、と感じています。

0 件のコメント:

コメントを投稿