Workflow Foundation 4 第三課 - 設計 Code Activity

原文出處:http://michaelchpeng.spaces.live.com/blog/cns!37633C3B61B57B57!1155.entry


前面我們很快的體驗了一下 WF 4 解決方案的建立,如果是在 WF 3,我接下來應該是要個別介紹不同的活動控制項,建立更複雜的應用程式。但是因為 WF 4 在架構上的調整,強制大家真的從包裝作業邏輯開始去建立應用程式流程。所以我們在這一課直接跳進 Activity 的設計,看看如何把之前的動作包裝到單一的活動控制項中,然後讓我們的流程使用這個活動控制項。感謝 WF 4,這件事情真的變的簡單很多,簡單到你根本差覺不到它和設計一個一般的類別有什麼差別。

首先我們在原本的 HelloWF4 專案中加入一個新的項目,然後在範本清單中選擇 Code Activity,指定類別名稱為 SayHelloInCode。在第一課中我提到過,活動控制項就實做上主要有兩類,一是純粹透過程式碼,二是用既有的活動控制項去組合。這一次我們就直接用 Code Activity,感受一下究竟有多簡單。

新建立的類別預設的程式碼如下:

我們可以看到,這個類別繼承了 CodeActivity 類別,唯一要實做的方法就是 Execute。其實之前在 WF 3.x 也是直接繼承一個類別,只是這個類別並不是直接從最底層的活動類別開始,而是從 SequenceActivity 開始,這就會牽涉到 Thread 的問題。以我們這裡的例子為例,如果我想要建立一個直接在主控台應用程式中顯示訊息的活動,直覺的方式是寫 Console.Write/Console.WriteLine 就好了。但是你在 WF 3 中會發現事實並非如此,因為你的自訂活動控制項是繼承自 SequenceActivity,它是個容器控制項,所以你一定要安排一個 Code 活動控制項,然後在它的 ExecuteCode 事件中加入輸出的程式碼。但是到了 WF 4 中,因為 CodeActivity 就是一個最基礎的活動控制項 (也是一個抽象類別),所以你可以完全透過程式碼處理,直接在 Execute 方法中 (而且一定要) 加上作業邏輯就行。這個類別是定義在 System.Activities 當中,所以你必須引用這個命名空間 (在範本中,這個命名空間已經自行引用)。

我把原來程式碼中不必要的宣告刪除掉,然後加上輸出程式碼,如下:

接下來為了能讓它反映到我們的 IntelliSense 環境中,所以進行了建置的動作。如果你去開啟 SayHello.xaml,進入到流程設計器中,你會發現這個活動控制項自動出現在工具箱中。不過你無法把它拖放到設計器當中,因為你並沒有安排對應的設計器,所以無法安排到設計環境中。

既然我們目前並不能直接透過設計工具安排到工作流程中,另一個暫時性的方案是直接從主程式中去載入這個活動控制項執行。別忘了,一個活動控制項本身也是一個流程 (或者說一個流程就是一個特別類型的活動)。所以我們接下來要做的,就是到 Module1 的 Main 程序中將原本載入 SayHello 類別執行的程式碼改成載入 SayHelloInCode:

 

WorkflowInvoker.Invoke(New SayHelloInCode())

修改完畢後,直接按下 Ctrl+F5,應用程式的結果就會是 SayHelloInCode 執行的結果。

從這個例子中,可以大致感受到建立一個以程式碼為主的活動控制項的過程。還是一樣,它和我們直接寫程式碼相較,並不會太有效率,還是有一些麻煩,但是額外的負擔並不大。而很到的好處,是至少在主要作業邏輯上具備有視覺化的「潛力」。事實上,這個應用程式隱含了一些架構上帶來的效益,是我們在表面上看不到的。例如若是我們要同時啟動四、五個 SayHelloInCode/SayHello 的流程實例,每一個作業都會自然而然的執行在不同的執行緒上,有自己獨立的生命週期。但是如果我們是自己的程式,沒有安排特定的執行緒管理程式碼,就會四、五個物件實例都跑在同一個執行緒上。這些事情等到我們的作業邏輯慢慢複雜了,就會有很明顯的區別。

另一方面,目前的活動控制項還沒有使用到參數或變數,所以被重複使用的機會不大。如果我們再加上設計器,讓參數的指定更為簡便,使用 WF 開發應用系統的效益就會逐漸浮現。在後面的課程中,我們會為活動控制項加上參數,也加上設計介面。