コンソールでWF

WFといえば、GUIでお絵かきが目立ちますが、本質は宣言的にプログラミング可能にするモデルだったりします。勉強のためGUIを使わずにWFのコーディングを行ってみたいと思います。まず、最初はHello, Worldから。
WFはActivityによって構成されます。ここでは、HelloWorldというActivityを作成します。

using System;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Serialization;

[assembly: XmlnsDefinition ("http://Na", "Na")]
namespace Na 
{
    public class HelloWorld : Activity
    {
        protected override ActivityExecutionStatus Execute (ActivityExecutionContext context)
        {
            Console.WriteLine ("Hello, World");
            return ActivityExecutionStatus.Closed;
        }
    }
}

Activityを継承します。また、XmlnsDefinition属性によってCLR名前空間とURLをマッピングします。

また、WFを実行するにはランタイムをホストします。

using System;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.Runtime;
using System.Xml;

namespace Na
{
    class Program 
    {
        static void Main ()
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime ())
            {
                TypeProvider tp = new TypeProvider (runtime);
                tp.AddAssemblyReference ("HelloWorld.dll");
                runtime.AddService (tp);
                runtime.StartRuntime ();

                WorkflowInstance instance = null;
                using (XmlTextReader reader = new XmlTextReader ("App.xoml"))
                {
                    instance = runtime.CreateWorkflow (reader);
                    instance.Start ();
                }

                Console.Read ();

                runtime.StopRuntime ();
            }
        }
    }
}

最後にApp.xomlファイルで作成したHelloWorldを使用してみましょう。

<SequenceActivity xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
    <HelloWorld xmlns="http://Na" />
    <HelloWorld xmlns="http://Na" />
    <HelloWorld xmlns="http://Na" />
</SequenceActivity>

SequenceActivityはWFが標準で持っているActivityで子要素をシーケンスに実行します。

実行結果はもちろんHello, World×3です。