如果你曾經負責開發企業ERP系統或者OA系統,工作流對你來說一定並不陌生。工作流(Workflow)是對工作流程及其各操作步驟之間業務規則 的抽象、概括、描述。工作流要解決的主要問題是:爲實現某個業務目標,在多個參與者之間,利用計算機,按某種預定規則自動傳遞文檔、信息或者任務。有見及 此,微軟在.NET 3.0基礎上發佈了WF,WCF,以及WCS(身份驗證解決方案),WPF(爲開發表現層而設)。WF正是解決企業核心問題的關鍵,通過WF可以輕鬆地輕 鬆地按照業務邏輯去實現開發,然後把WF發佈爲Web服務,這樣客戶端與服務與服務器端通訊就不會再受開發語言的影響,通過Web服務就可以輕鬆調用WF 去實現業務操作。
下面以一個簡單的訂單錄入系統爲例子,爲你介紹一下如何將Workflow工作流發佈爲Web服務。
爲了實現一個持久化工作流,首先以實用工具sqlcmd來建立一個本地數據庫,打開命令提示符窗口,輸入
sqlcom -S localhost/SQLEXPRRESS -E -Q "create database WorkflowPersistence"
然後打開文件夾
/Microsoft.Net/Framework/v3.0/Windows Workflow Foundation/SQL/[Lauguage]
裏面有2個腳本文件
SqlPersistenceService_Schema.sql , SqlPersistenceService_Logic.sql
在數據庫WorkflowPersistence上運行此腳本文件,數據庫就可以成功創建。
實例描述:當客戶第一次加入訂單時通過Web服務調用Start方法來創建新的Workflow對象實例,之後可以多次調用AddOrder方法添加訂 單,在訂單沒有提交前,此工作流對象實例會處於一個持久化的狀態。當服務器處於空閒狀態下Workflow對象的有關數據會存儲於 WorkflowPersitence數據庫裏面,這樣做可以有效減少服務器緩存的壓力。最後調用End方法提交訂單後,Workflow工作流對象纔會 結束,Workflow對象的數據就會在數據庫中被刪除。
這裏先定義一個Order類,別忘記給對象加上Serializable串行化屬性
[Serializable]
public class Order
{...}
爲Order開發一個操作類OrderManager,裏面包括一個方法AddOrder,當每加入一個Order,方法就會返回新加入Order的ID
public class OrderManager
{
public int AddOrder(Order order)
{..........}
}
現在對應此實例我們先開發一個接口IService_T1,Start方法表示啓動此Workflow工作流,而End表示此工作流完結
namespace Microsoft.IService
{
public interface IService_T1
{
void Start();
int AddOrder(Order order);
void End();
}
}
下圖是這個Workflow的完整視圖,我們先使用webServiceInputActivity1來啓動服務
在這裏將webServiceInputActivity1的IsActivating屬性設置爲True,這意味着以此活動激活此Workflow對象實例,然後把InterfaceType設置爲Microsoft.IService.IService_T1,並把MethodName設置爲Start,這時候當客戶端調用Start方法時,Workflow對象實例就會被激活。
然後設置WhileActivity的循環條件(this.IsRepeated==true),這說明只要IsRepeated的值爲True, WhileActivity就可以持續運行,則此Workflow處於持久化狀態
現在爲listenActivity1設置2個事件驅動活動,在左邊的事件驅動活動中,分別加入webServiceInputActivity2, codeActivity1, webServiceOutputActivity1。將webServiceInputActivity2的InterfaceType設置爲 Microsoft.IService.IService_T1,再把MethodName設置爲AddOrder,將AddOrder方法中的參數order綁定爲此Workflow對象中的參數_order (參考完整代碼),這樣就可以通過webServiceInputActivity2調動AddOrder方法。然後在codeActivity的codeActivity_ExecuteCode方法中加入操作代碼。
最後通過webServiceOutputActivity1結束操作,把InputActivityName屬性設置爲webServiceInputActivity2,將ReturnValue綁定變量id 。這樣系統在插入Order後就可以獲取AddOrder方法的返回值(int) id。
現在,可以在右邊的事件驅動活動中,插入一個webServiceInputActivity3,把InterfaceType設置爲Microsoft.IService.IService_T1,把MethodName設置爲End,然後添加事件InputReceived的處理方法webServiceInputActivity3_InputReceived,通過此方法把IsRepeate屬性設置爲false,這樣就可以調動此活動來終於循環,結束此工作流。
此爲該Workflow的完整代碼:
namespace Microsoft.Workflows
{
public sealed partial class Workflow: SequentialWorkflowActivity
{
public Order _order
;
public int id
;
public bool IsRepeate = true
;
public Workflow2()
{
InitializeComponent();
}
//當調用AddOrder方法時執行此操作,通過orderManager對象插入order,最後返回值orderID賦值給此Workflow參數id
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
OrderManager orderManager=new OrderManager();
int orderID=orderManager.AddOrder(order);
this.id=orderID;
}
//當調用webServiceInputActivity3活動時,把IsRepeate的值設置爲false,這樣可以終止循環給束此工作流對象。
private void webServiceInputActivity3_InputReceived(object sender, EventArgs e)
{
IsRepeate = false;
}
}
}
這時候右鍵點擊此“項目”,選擇 “把此Workflow作爲Web發佈”,得到以下ASMX文件
Microsoft.Workflows.Workflow2_WebService.asmx
<%@WebService Class="Microsoft.Workflows.Workflow2_WebService" %>
添加配置文件
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="WorkflowRuntime"
type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection,
System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
</configSections>
<WorkflowRuntime Name="WorkflowServiceContainer">
<Services>
<add
type="System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService,
System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add
type="System.Workflow.Runtime.Hosting.DefaultWorkflowCommitWorkBatchService,
System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"/>
<add
type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" UnloadOnIdle="true"
LoadIntervalSeconds="5" ConnectionString="Data Source=LESLIE-PC;Initial
Catalog=WorkflowPersistence;Integrated Security=True"/>
//這裏是爲Workflow添加SQL數據庫持久化服務,因爲這裏要是測試持久化的工作流,此配置是必須的。
</Services>
</WorkflowRuntime>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="true"/>
<authentication mode="Windows"/>
<httpModules>
<add
type="System.Workflow.Runtime.Hosting.WorkflowWebHostingModule,
System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" name="WorkflowHost"/>
</httpModules>
</system.web>
</configuration>
調用Start方法啓動Workflow,然後就可以直接調用AddOrder方法,你會發現與上一篇實例不同的是,在上一篇的例子中,每個實例只允許調用一次,當頁面未被重新加載時多次調用就會出現錯誤提示。而在這一篇的例子中,AddOrder可以多次調用,並能正常運行,這就證明了你調用的Workflow的實例對象已經一個持久化工作流,當你未調用End結束服務時,此工作流對象都可以正運行。
最後,你可以調用End方法來結束操作,當操作結束後,再調用AddOrder,系統就會出現錯誤顯示:
System.InvalidOperationException: 在狀態持久性存儲中找不到 ID 爲“3a8b9688-fb3f-4a10-bb84-6bf99c30119a”的工作流。
總結一下,通過持久化服務流的開發,可以保持工作流實例的活動狀態,這樣就可以通過多個Web服務進行相互調用。使用這種技術來實現基於工作流的應用程序 ,就可以將它們通過Web服務公開經客戶端,並能維持工作狀態。
Web服務和WF可以實現相互調用,在這兩章裏面,爲大家介紹如何將工作流發佈爲Web服務,下一章將爲大家介紹通過InvokeWebServiceWorkflow在WF裏面調用Web服務。
對NET系統開發有興趣的朋友,請加入QQ羣:NET技術開發聯盟 59557329 一起討論