首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WF 4.0 自訂持久化實作(XML 儲存至 SQL Server)

     編輯:關於.NET

WF 4 內建 SqlWorkflowInstanceStore 功能強大但結構複雜(10 資料表、24 預存程序)。本文實作自訂持久化,同樣儲存至 SQL Server,但結構極簡。

1. 資料表設計

單一資料表 InstancesTable:

2. XmlWorkflowInstanceStore 繼承 InstanceStore

覆寫 BeginTryCommand 處理三大核心命令:

  • CreateWorkflowOwnerCommand:建立實例擁有者綁定
  • SaveWorkflowCommand:序列化實例資料為 XML 存入資料表
  • LoadWorkflowCommand:從資料表讀取 XML 反序列化還原實例

核心程式碼:

public class XmlWorkflowInstanceStore : InstanceStore {
    public Guid ownerInstanceID;
    public XmlWorkflowInstanceStore() : this(Guid.NewGuid()) {}
    public XmlWorkflowInstanceStore(Guid id) { ownerInstanceID = id; }

    protected override bool TryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout) {
        return EndTryCommand(BeginTryCommand(context, command, timeout, null, null));
    }

    protected override IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state) {
        IDictionary<XName, InstanceValue> data = null;
        if (command is CreateWorkflowOwnerCommand) {
            context.BindInstanceOwner(ownerInstanceID, Guid.NewGuid());
        } else if (command is SaveWorkflowCommand) {
            data = ((SaveWorkflowCommand)command).InstanceData;
            Save(data);
        } else if (command is LoadWorkflowCommand) {
            try {
                var obj = InstancesTableBiz.GetInstancesTable(this.ownerInstanceID);
                byte[] bs = Encoding.UTF8.GetBytes(obj.InstanceXML);
                using (var ms = new MemoryStream(bs)) {
                    data = LoadInstanceDataFromFile(ms);
                }
                context.LoadedInstance(InstanceState.Initialized, data, null, null, null);
            } catch (Exception ex) { throw new PersistenceException(ex.Message); }
        }
        return new CompletedAsyncResult<bool>(true, callback, state);
    }

    protected override bool EndTryCommand(IAsyncResult result) {
        return CompletedAsyncResult<bool>.End(result);
    }

    // XML 反序列化為 Dictionary
    IDictionary<XName, InstanceValue> LoadInstanceDataFromFile(Stream inputStream) { ... }

    // 序列化儲存至資料表
    void Save(IDictionary<XName, InstanceValue> instanceData) { ... }

    // 輔助序列化/反序列化方法
    object DeserializeObject(NetDataContractSerializer serializer, XmlElement element) { ... }
    XmlElement SerializeObject(string elementName, object o, XmlDocument doc) { ... }
}

3. 書籤活動

public sealed class Read<TResult> : NativeActivity<TResult> {
    public string BookmarkName { get; set; }
    protected override bool CanInduceIdle { get { return true; } }
    protected override void Execute(NativeActivityContext context) {
        context.CreateBookmark(this.BookmarkName, new BookmarkCallback(this.Continue));
    }
    void Continue(NativeActivityContext context, Bookmark bookmark, object obj) {
        this.Result.Set(context, (TResult)obj);
    }
}

4. 三階段書籤流程設計

5. 使用自訂持久化

XmlWorkflowInstanceStore instanceStore = new XmlWorkflowInstanceStore();
WorkflowApplication application = new WorkflowApplication(new Activity1());
application.InstanceStore = instanceStore;
application.PersistableIdle = e => PersistableIdleAction.Unload;
application.Completed = args => Console.WriteLine("Completed: {0}", args.CompletionState);
application.Unloaded = args => { Console.WriteLine("Unloaded"); instanceUnloaded.Set(); };
instanceStore.ownerInstanceID = application.Id;
application.Run();
instanceUnloaded.WaitOne();
return application.Id;

6. 示範說明

  • Start.aspx:啟動流程
  • Default.aspx:進行 A、B、C 三關審核

專案實際應用:所有審核流程使用書籤機制,比 Demo 複雜得多。自訂持久化另一優勢:微軟內建持久化在流程結束後自動刪除實例記錄,自訂版可保留完整歷程。

原始碼下載:WorkflowConsoleApplication3.rar

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved