シンプルにWorkflowを実行してみる

WFが出ているが、あまり利用例などが出てこない。この点は僕の過去の経験からはある程度予想していたが、それでも少ないようにも感じている。良い技術なのにもったいない。
そこで非常にシンプルな使い方としてWFのシーケンシャルフローを(ジェネラル)フローチャート*1な利用する方法を紹介することしよう。
シナリオとしてはASP.NETで、イベント待ちなどや非同期的な処理がないインメモリで実行できるシーケンシャルフローを処理することにする。
WFではワークフローの実行において永続化やスケジューラ(スレッド制御)の仕組みが隠ぺいされる。しかし、実際にはこれらの機能はサービスとして登録する必要があり、このあたりの仕組みの理解が必要になる。
上記のシナリオは永続化をしないで、かつ、スケジューラは呼び出し元のスレッドのみを使うようにすることで、できるだけシンプルにWFを使うことを考慮したシナリオということになる。

これであれば必要な作業は限られていて3ステップで10分もあれば動作を確認できる。

1.Workflowランタイムの用意(Global.asaxの作成)
2.シーケンシャルフローの作成(シーケンシャルフローの作成)
3.シーケンシャルフローの実行(実行ページの作成)


1.Workflowランタイムの用意
これはASP.NETアプリケーションの起動時に作成して提供するようにするのが簡単。

Global.asax

<%@ Application Language="C#" %>
<%@ Import Namespace="System.Workflow.Runtime" %>
<script runat="server">
    void Application_Start(object sender, EventArgs e) 
    {
        WorkflowRuntime w = new WorkflowRuntime();
        w.AddService(new System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService());
        Application["WorkflowRuntime"] = w;
    }
    void Application_End(object sender, EventArgs e) 
    {
        if (WorkflowRuntime != null)
        {
            WorkflowRuntime.Dispose();
        }
    }       
    public WorkflowRuntime WorkflowRuntime
    {
        get {
            return (WorkflowRuntime)(Application["WorkflowRuntime"]); 
        }
    } 
</script>


2.シーケンシャルフローの作成
適当なものを作成すればOK。ただし、今回は単純にするためにイベント待ちなど一時的にでも待ちにならないものにしておく。


3.シーケンシャルフローの実行
ManualWorkflowSchedulerServiceのRunWorkflowを利用するワークフローのインスタンスをマニュアルで呼び出し元と同じスレッドで実行することができる。

SimpleWorkflow.aspx

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Workflow.Runtime" %>
<%@ Import Namespace="System.Workflow.Runtime.Hosting" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    protected void Page_Load(object sender, EventArgs e)
    {
        WorkflowRuntime runtime = ApplicationInstance.WorkflowRuntime;

        WorkflowInstance workflow;
        workflow = runtime.CreateWorkflow(typeof(WorkflowSample.Workflow.Workflow1));
        workflow.Start();

        ManualWorkflowSchedulerService scheduler;
        scheduler = runtime.GetService<ManualWorkflowSchedulerService>();
        scheduler.RunWorkflow(workflow.InstanceId);

    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>無題のページ</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
    </div>
    </form>
</body>
</html>

どうだろう。とりあえず、シンプルで通常のメソッド呼び出しとほぼ同じような挙動でWorkflow(シーケンシャルフロー)を呼び出すことができる点は、非常にお手軽な利用法ではないかな。

*1:懐かしい単語の響き