通過XOML或者XAML的方式創建和啟動工作流

作者: 陳希章  來源: 博客園  發布時間: 2010-10-09 17:29  閱讀: 1728 次  推薦: 0   原文鏈接   [收藏]  
摘要:本篇作者通過實例講解了如何基于XOML完成工作流的定義和創建。

  在Workflow Foundation中,提供了多種設計工作流的方式。例如:

  1、純代碼的方式(C#)
  2、代碼分離的方式(XOML+C#)

  以上兩種,可以從Visual Studio提供的項目模板中選擇:

image  他們在設計器中看起來是如下的:

image  xoml是一種特殊的XML格式,它可以描述流程。例如下面這樣的一個流程:

image  它用XOML描述的話,大致如下:

 
<SequentialWorkflowActivity x:Class="WorkflowConsoleApplication1.Workflow2" x:Name="Workflow2" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<CodeActivity x:Name="codeActivity1" />
<IfElseActivity x:Name="ifElseActivity1">
<IfElseBranchActivity x:Name="ifElseBranchActivity1">
<CodeActivity x:Name="codeActivity2" />
</IfElseBranchActivity>
<IfElseBranchActivity x:Name="ifElseBranchActivity2">
<CodeActivity x:Name="codeActivity3" />
</IfElseBranchActivity>
</IfElseActivity>
</SequentialWorkflowActivity>

  雖然上面這樣的XML確實可以描述流程,但流程所涉及的一些特殊邏輯,則可能還是需要寫代碼。這兩個部分,最終還是需要編譯成一個類型出來。所以,實際上上面的兩種方式沒有本質的區別。

  這里要介紹的是一種純XOML的方式:我們能不能全部用XOML來實現對流程的定義?如果這樣的話,我們就可以實現更加動態化的流程,因為如果存在額外的代碼,就無需編譯,而是可以通過直接修改XOML文件就完成流程的修改。

  答案是:可以的。但有一個前提,既然我們不想用代碼,那么流程中所使用的Activity就應該都是可以通過配置即可完成工作的。

  通常,我們需要編寫自定義Activity來實現這樣的需求。例如,我們可以做一個最簡單的Activity,它只是根據用戶輸入的一個參數,負責在屏幕上打印一個消息。

 
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Linq;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;

namespace WorkflowConsoleApplication1
{

public partial class MyActivity :Activity
{

public MyActivity()
{
InitializeComponent();
}


public string Message { get; set; }

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
Console.WriteLine(Message);

return base.Execute(executionContext);
}
}
}

  為了演示如何直接通過XOML定義的方式使用這個自定義Activity,我們可以通過下面的代碼生成一段XOML :

 
var workflow = new SequenceActivity();
workflow.Activities.Add(
new MyActivity() { Message = "Hello,World" });
var serializer
= new WorkflowMarkupSerializer();
serializer.Serialize(
XmlWriter.Create(
"test.xoml",new XmlWriterSettings(){CloseOutput=true}), workflow);

  以上代碼的意思是,創建一個SequenceActivity,并且在其中添加我們自定義的這個Activity。代碼執行完成之后,生成的那個test.xoml的內容如下:

 
<?xml version="1.0" encoding="utf-8"?><SequenceActivity x:Name="SequenceActivity" xmlns:ns0="clr-namespace:WorkflowConsoleApplication1;Assembly=WorkflowConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<ns0:MyActivity Message="Hello,World" x:Name="myActivity1" />
</SequenceActivity>

  這里請仔細觀察一下與之前那段xoml的區別:

  1.頂層的Activity,不再包含x:Class定義。(因為現在沒有了代碼文件,Class就無從說起了)
  2.內部所有的自定義Activity,都需要預先定義有關的namespace,引用到它們所在的Assembly
  3.自定義Activity的設置,直接通過屬性完成

  那么,如何利用上面這樣的定義,去創建并運行流程呢?  

 
var instance2 = workflowRuntime.CreateWorkflow(
XmlReader.Create(
"test.xoml"));
instance2.Start();

  如果我們需要修改流程定義,則直接可以修改那個XOML文件,而無需編譯程序。例如我們將Message修改為“Hello,Workflow”:

image  則運行結果如下:

image  其實,只要我們愿意,我們甚至可以將這些定義的字符串保存在愛數據庫中,然后通過下面代碼創建并啟動流程:

 
var definition ="<?xml version=\"1.0\" encoding=\"utf-8\"?><SequenceActivity x:Name=\"SequenceActivity\" xmlns:ns0=\"clr-namespace:WorkflowConsoleApplication1;Assembly=WorkflowConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/workflow\"><ns0:MyActivity Message=\"Hello,Workflow\" x:Name=\"myActivity1\" /></SequenceActivity>";
//這里還可以從數據庫將該定義讀取出來

var reader = XmlReader.Create(new StringReader(definition));
var workflow
= workflowRuntime.CreateWorkflow(reader);
workflow.Start();
0
0
 
標簽:WF
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()