[WF 4 (最終回)] デザイナー リホスティング (Designer Rehosting) とカスタムアプリケーション

環境 : Visual Studio 2010 Beta 2 (.NET Framework 4)

WF 4

  1. そのアイデアとベースクラスの変更
  2. コードいらずのワークフロー (入門)
  3. ワークフローのコードと XAML の内部
  4. フローチャート (FlowCharts)
  5. アクティビティ (基礎)
  6. アクティビティコンテキスト (context) と変数 (Variable) の意義
  7. アクティビティにおけるさまざまな実行管理
  8. アクティビティのデリゲート
  9. アクティビティの非同期実行
  10. アクティビティデザイナー
  11. ブックマーク
  12. Workflow Extensions と 永続化、トラッキング
  13. デザイナーリホスティングとカスタムアプリケーション

こんにちは。

強引に最終回です。最後は、.NET 4 の WF デザイナーを使ったカスタムアプリケーションについて説明します。

せっかくモデル駆動なワークフローを使用するわけですから、「実際のフローの構築はエンドユーザーに明け渡す」など、WF のメリットをさらに享受したくなるはずです。WF 4 が今までの WF よりもさらに優れている点は、こうしたアプリケーションにも充分に配慮された仕組みが提供されている点です。

以降では、WF 4 のワークフローデザイナーを使ったカスタムアプリケーションの基本を理解します。こうしたデザイナー機能を提供することを「デザイナーリホスティング」 (Designer Rehosting) と呼びます。

Note : これまでの WF (WF 3.5) のリホスティングでは、デザイナーに関するベース知識、検証 (Validation) の理解など、非常に高度な知識が必要 (= エキスパートでないと組めない) でした。
詳細は、以前、「
Rehosting を使ったエンドユーザへのワークフロー公開」で紹介しましたが、このポストで紹介したサンプルはあえて簡単な例であり、例えば、ツールボックスの表示などもおこなおうとすると、さらに、この 10 倍近くの難解なコードを記述する必要がありました。。。(私の知る限り、日本でこうした高度な実装をおこなっていた企業はごく一部です。)
以降で、WF 4 が、いかに簡単になったかを実感してください。

ワークフローリホスティングの基本アプリケーション

これまでの連載を見て頂いておわかりのように、Visual Studio を使ったワークフロー開発では、ワークフローの「デザイナー ビュー」、「ツールボックス」、「プロパティ ビュー」の 3 つの UIElement が表示されており、ワークフロー構築ではこれらを使用する必要があります。

WF 4 では、これらは、すべてカスタムアプリケーションでも利用しやすいように部品化されています。
今回は、以下の簡単な手順で実装します。

  1. 各アクティビティのデザイン情報を登録するため、デザイナー メタデータ (DesignerMetadata) を呼ばれるものを登録する (コードで登録する)
  2. デザイナー ビューとプロパティ ビュー (PropertyInspectorView) は、コードで挿入する (あらかじめ、XAML 上に Grid などを準備しておく)
  3. System.Activities.Presentation.Toolbox.ToolboxControl クラスを XAML のマークアップで挿入する

では、実装してみましょう。

まず、[WPF アプリケーション] のプロジェクトを新規作成します。作成されたプロジェクトに、System.Activities.dll, System.Activities.Presentation.dll, System.Activities.Core.Presentation.dll を参照追加してください。

今回は、横に、上記の 3 つの UIElement を並べて表示するため、以下の通り XAML を記述します。(勿論、デザイナー上でマウスを使って設定してもかまいません。)

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="4*"/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0" Name="ToolboxArea"/>
        <Border Grid.Column="1" Name="DesignerArea"/>
        <Border Grid.Column="2" Name="PropertyArea"/>
    </Grid>
</Window>

Visual Studio での動きを思い出して頂いておわかりの通り、デザイナービューの上で選択されたアイテムのプロパティ情報がプロパティ ビューに表示されまず。このように、デザイナー ビューとプロパティ ビューは相互に関連付けられています。この関連付けられた双方のビューを挿入するには、以下のように WorkflowDesigner というオブジェクトをいったん作成して、この WorkflowDesigner からデザイナー ビューとプロパティ ビューを取得して、上記の Grid 上に挿入します。

コードビハインド (MainWindow.xaml.cs) に、以下の override メソッドを実装して、このデザイナービューとプロパティビューを (上記の Grid 上に) 配置します。

. . .

using System.Activities.Core.Presentation;
using System.Activities.Presentation;
using System.Activities.Statements;

protected override void OnInitialized(EventArgs e)
{
    base.OnInitialized(e);

    // register designer metadata of Activities
    DesignerMetadata metadata = new DesignerMetadata();
    metadata.Register();

    // create workflow designer
    WorkflowDesigner designer = new WorkflowDesigner();

    // insert "Sequence" activity
    // (we must call "Load" once !)
    designer.Load(new Sequence());

    // insert UIElement (designer view, property view)
    DesignerArea.Child = designer.View;
    PropertyArea.Child = designer.PropertyInspectorView;
}

ここで注意点ですが、Load は、必ず 1 回だけ呼び出してください。大阪の串カツ同様、2 回の呼び出し (二度漬け) も禁止です !

さいごに、ツールボックスを追加します。(今度は、XAML で追加します。)
まず、XML 名前空間として下記を追加します。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
        xmlns:sapt="clr-namespace:System.Activities.Presentation.Toolbox;assembly=System.Activities.Presentation"

. . .

以下の通り XAML を記述し、0 列目の Grid にツールボックスコントロールを挿入します。
ツールボックスには、試しに、Sequence アクティビティと WriteLine アクティビティを挿入しておきましょう。

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sapt="clr-namespace:System.Activities.Presentation.Toolbox;assembly=System.Activities.Presentation"
    Title="MainWindow" Height="350" Width="525">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="3*"/>
      <ColumnDefinition Width="4*"/>
      <ColumnDefinition Width="3*"/>
    </Grid.ColumnDefinitions>
    <Border Grid.Column="0" Name="ToolboxArea">
      <sapt:ToolboxControl>
        <sapt:ToolboxCategory CategoryName="使えるアイテム">
          <sapt:ToolboxItemWrapper AssemblyName="System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" >
            <sapt:ToolboxItemWrapper.ToolName>
              System.Activities.Statements.Sequence
            </sapt:ToolboxItemWrapper.ToolName>
          </sapt:ToolboxItemWrapper>
          <sapt:ToolboxItemWrapper  AssemblyName="System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <sapt:ToolboxItemWrapper.ToolName>
              System.Activities.Statements.WriteLine
            </sapt:ToolboxItemWrapper.ToolName>
          </sapt:ToolboxItemWrapper>
        </sapt:ToolboxCategory>
      </sapt:ToolboxControl>
    </Border>
    <Border Grid.Column="1" Name="DesignerArea"/>
    <Border Grid.Column="2" Name="PropertyArea"/>
  </Grid>
</Window>

実行すると、下図の通り表示されます。ちゃんとドラッグ アンド ドロップも可能です。
(なお、64 bit 環境で動かしている場合は、プロジェクトのプラットフォーム ターゲットが Any CPU になっていることを確認してください。)

もちろん、第10回で説明したカスタム アクティビティとアクティビティ デザイナーも、上記のリホスティング アプリケーションで使用できます。(簡単です。)
カスタム アクティビティ (アクティビティ デザイナー含む) のライブラリを参照追加し、XAML に、下記の通り ToolboxItemWrapper を追加すれば、それで終了です。(カスタム アクティビティのアセンブリに署名をしている場合は、アセンブリの厳密名を指定してください。)

<Grid>
  . . .

  <Border Grid.Column="0" Name="ToolboxArea">
    <sapt:ToolboxControl>
      <sapt:ToolboxCategory CategoryName="使えるアイテム">
        <sapt:ToolboxItemWrapper AssemblyName="System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" >
          . . .

        </sapt:ToolboxItemWrapper>
        <sapt:ToolboxItemWrapper  AssemblyName="System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
          . . .

        </sapt:ToolboxItemWrapper>

        <sapt:ToolboxItemWrapper  AssemblyName="MyCustomActivities">
          <sapt:ToolboxItemWrapper.ToolName>
            MyCustomActivities.ReadLine
          </sapt:ToolboxItemWrapper.ToolName>
        </sapt:ToolboxItemWrapper>

      </sapt:ToolboxCategory>
    </sapt:ToolboxControl>
  </Border>
  <Border . . . 
  <Border . . .
</Grid>

 

XAML ファイルへの保存とロード (Save / Load) の機能追加

ここまでは基本的なリホスティングのみのアプリケーションでしたが、実際の開発では、エンドユーザーが上記で作成したワークフローを保存したり、実行したり、といった処理が必要になるでしょう。
以降では、この方法を簡単に説明します。

まずは、保存とロード (開く) の機能を実装しましょう。
作成したワークフローの内容を XAML としてファイル (file) に保存するには、上記で使用した WorkflowDesigner クラスの Save メソッドを呼べばOKです。逆に XAML に保存された内容をロードするには、Load(string filename) メソッドを使用します。

protected WorkflowDesigner designer;

protected override void OnInitialized(EventArgs e)
{
    . . .(same as above)

    designer = new WorkflowDesigner();
    designer.Load(new Sequence());

    DesignerArea.Child = designer.View;
    PropertyArea.Child = designer.PropertyInspectorView;
}

private void FileSave_Click(object sender, RoutedEventArgs e)
{
    designer.Save(@"c:tmpworkflow.xaml");
}

private void FileOpen_Click(object sender, RoutedEventArgs e)
{
    // Workflowdesigner is already loaded. So, we'll create new one.
    designer = new WorkflowDesigner();
    designer.Load(@"c:tmpworkflow.xaml");

    DesignerArea.Child = designer.View;
    PropertyArea.Child = designer.PropertyInspectorView;
}

「Load は必ず 1 回だけ呼び出さなければならない」という大阪ルールを思い出してください。このため、上記の通り、新しい WorkflowDesigner のインスタンスを作成して、またロードをやりなおしています。

ワークフローの実行 (Execute)

上記で保存された XAML ファイルを開いて、ワークフローを実行するのも簡単です。
第 3 回で使用した XamlServices を使用するのみです。

private void ExecuteMenu_Click(object sender, RoutedEventArgs e)
{
    Activity a = (Activity) System.Xaml.XamlServices.Load(@"c:tmpworkflow.xaml");
    WorkflowInvoker.Invoke(a);
}

まとめ 

今回から、このように、リホスティングのカスタムアプリが “断然簡単に” なっていますので、WF をバックエンドのエンジンとして使用した高度なカスタムプロダクトや、エンドユーザーに業務フローの構築・運用を委ねた情報システムアプリケーションなど、幅広い範囲で “現実的に” デザイナーリホスティングを活用していくことが可能です。

以上で、本シリーズは終了しますが、Tech Days では、ここで紹介した WF の基本をザッと流して、WCF、ワークフローサービス、AppFabric についてお話する予定です。

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s