WF工作流技術內幕 —— 通過Web服務調用Workflow工作流(開發持久化工作流)

如果你曾經負責開發企業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 一起討論  點擊這裏加入此羣

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章