• WF4.0自定义持久化


        WF4提供了强大的持久化的功能,ms提供了SqlWorkflowInstanceStore 来进行SqlServer的持久化,我研究了一下,DB里面有10个数据表,24个存储过程。功能非常强大,但是也逻辑也比较复杂。这里我介绍自定义的持久化。持久化的存储器也SqlServer。

    1、设计数据表,表结构非常简单,如下图所示:

      

    2、自定义的SqlServerWorkflowInstanceStore继承了InstanceStore:

    代码
     public class SqlServerWorkflowInstanceStore : InstanceStore
        {
          
    public  Guid ownerInstanceID;
            
            
    public SqlServerWorkflowInstanceStore() : this(Guid.NewGuid())
            {

            }

            
    public SqlServerWorkflowInstanceStore(Guid id)
            {
                ownerInstanceID 
    = id;
            }

            
    //Synchronous version of the Begin/EndTryCommand functions
            protected override bool TryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout)
            {
                
    return EndTryCommand(BeginTryCommand(context, command, timeout, nullnull));
            }

            
    //The persistence engine will send a variety of commands to the configured InstanceStore,
            
    //such as CreateWorkflowOwnerCommand, SaveWorkflowCommand, and LoadWorkflowCommand.
            
    //This method is where we will handle those commands
            protected override IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
            {
                IDictionary
    <System.Xml.Linq.XName, InstanceValue> data = null;

                
    //The CreateWorkflowOwner command instructs the instance store to create a new instance owner bound to the instanace handle
                if (command is CreateWorkflowOwnerCommand)
                {
                    context.BindInstanceOwner(ownerInstanceID, Guid.NewGuid());
                }
                
    //The SaveWorkflow command instructs the instance store to modify the instance bound to the instance handle or an instance key
                else if (command is SaveWorkflowCommand)
                {
                    SaveWorkflowCommand saveCommand 
    = (SaveWorkflowCommand)command;
                    data 
    = saveCommand.InstanceData;
                    Save(data);
                }

                else if (command is LoadWorkflowCommand)
                {

                    
    try
                    {
                            InstancesTable obj 
    = InstancesTableBiz.GetInstancesTable(this.ownerInstanceID);
                            System.Text.UTF8Encoding utf8 
    = new System.Text.UTF8Encoding();
                            
    byte[] bs = utf8.GetBytes(obj.InstanceXML);
                            System.IO.MemoryStream memoryStream 
    = new System.IO.MemoryStream(bs);
                            data 
    = LoadInstanceDataFromFile(memoryStream);
                            context.LoadedInstance(InstanceState.Initialized, data, 
    nullnullnull);
                    }
                    
    catch (Exception exception)
                    {
                        
    throw new PersistenceException(exception.Message);
                    }
                }

                
    return new CompletedAsyncResult<bool>(true, callback, state);
            }

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

            IDictionary<System.Xml.Linq.XName, InstanceValue> LoadInstanceDataFromFile(Stream inputStream)
            {
                IDictionary
    <System.Xml.Linq.XName, InstanceValue> data = new Dictionary<System.Xml.Linq.XName, InstanceValue>();

                NetDataContractSerializer s 
    = new NetDataContractSerializer();

                XmlReader rdr 
    = XmlReader.Create(inputStream);
                XmlDocument doc 
    = new XmlDocument();
                doc.Load(rdr);

                XmlNodeList instances 
    = doc.GetElementsByTagName("InstanceValue");
                
    foreach (XmlElement instanceElement in instances)
                {
                    XmlElement keyElement 
    = (XmlElement)instanceElement.SelectSingleNode("descendant::key");
                    System.Xml.Linq.XName key 
    = (System.Xml.Linq.XName)DeserializeObject(s, keyElement);

                    XmlElement valueElement 
    = (XmlElement)instanceElement.SelectSingleNode("descendant::value");
                    
    object value = DeserializeObject(s, valueElement);
                    InstanceValue instVal 
    = new InstanceValue(value);

                    data.Add(key, instVal);
                }

                
    return data;
            }

            
    object DeserializeObject(NetDataContractSerializer serializer, XmlElement element)
            {
                
    object deserializedObject = null;

                MemoryStream stm 
    = new MemoryStream();
                XmlDictionaryWriter wtr 
    = XmlDictionaryWriter.CreateTextWriter(stm);
                element.WriteContentTo(wtr);
                wtr.Flush();
                stm.Position 
    = 0;

                deserializedObject 
    = serializer.Deserialize(stm);

                
    return deserializedObject;
            }

            void Save(IDictionary<System.Xml.Linq.XName, InstanceValue> instanceData)
            {

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(
    "<InstanceValues/>");
                
                
    foreach (KeyValuePair<System.Xml.Linq.XName,InstanceValue> valPair in instanceData)
                {
                    XmlElement newInstance 
    = doc.CreateElement("InstanceValue");

                    XmlElement newKey 
    = SerializeObject("key", valPair.Key, doc);
                    newInstance.AppendChild(newKey);

                    XmlElement newValue 
    = SerializeObject("value", valPair.Value.Value, doc);
                    newInstance.AppendChild(newValue);

                    doc.DocumentElement.AppendChild(newInstance);
                }

                if (!string.IsNullOrEmpty(InstancesTableBiz.GetInstancesTable(this.ownerInstanceID).InstanceXML))
                {
                    InstancesTable obj 
    = InstancesTableBiz.GetInstancesTable(this.ownerInstanceID);
                    obj.InstanceXML 
    = doc.InnerXml;
                    InstancesTableBiz.UpdateInstancesTable(obj);
                }
                
    else
                {
                    InstancesTable obj 
    = new InstancesTable();
                    obj.id 
    = this.ownerInstanceID;
                    obj.InstanceXML 
    = doc.InnerXml;
                    InstancesTableBiz.AddInstancesTable(obj);
                }
       
           }

            XmlElement SerializeObject(
    string elementName, object o, XmlDocument doc)
            {
                NetDataContractSerializer s 
    = new NetDataContractSerializer();
                XmlElement newElement 
    = doc.CreateElement(elementName);
                MemoryStream stm 
    = new MemoryStream();
                s.Serialize(stm, o);
                stm.Position 
    = 0;
                StreamReader rdr 
    = new StreamReader(stm);
                newElement.InnerXml 
    = rdr.ReadToEnd();
                
    return newElement;
            }  
        }

    3、设计书签类:

    代码
        public sealed class Read<TResult> : NativeActivity<TResult>
        {
            
    public Read()
                : 
    base()
            {
            }

            
    public string BookmarkName { getset; }

            
    // Must return true for a NativeActivity that creates a bookmark
            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、自定义持久化的使用

    代码
      SqlServerWorkflowInstanceStore  instanceStore = new  SqlServerWorkflowInstanceStore ();

                WorkflowApplication application 
    = new WorkflowApplication(new Activity1());

                application.InstanceStore 
    = instanceStore;

                application.PersistableIdle 
    = (e) =>
                {
                    
    return PersistableIdleAction.Unload;
                };
                application.Completed 
    = (workflowApplicationCompletedEventArgs) =>
                {
                    Console.WriteLine(
    "\nWorkflowApplication has Completed in the {0} state.", workflowApplicationCompletedEventArgs.CompletionState);
                };

                application.Unloaded 
    = (workflowApplicationEventArgs) =>
                {
                    Console.WriteLine(
    "WorkflowApplication has Unloaded\n");
                    instanceUnloaded.Set();
                };

                instanceStore.ownerInstanceID 
    = application.Id;
            
                
    // continue executing this instance
                application.Run();

               
    //string a= application.GetBookmarks()[0].BookmarkName;

                instanceUnloaded.WaitOne();

                
    return application.Id; ;

    6、Demo说明:

        在Start.aspx,启动一个流程

        在Default.aspx,进行A,B,C三个站的审核。

    备注:运行环境是VS2010 BETA2。

    代码:/Files/zhuqil/WorkflowConsoleApplication3.rar



    (全文完)


    以下为广告部分

    您部署的HTTPS网站安全吗?

    如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

    SSL检测评估

    快速了解HTTPS网站安全情况。

    安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

    SSL证书工具

    安装部署SSL证书变得更方便。

    SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

    SSL漏洞检测

    让服务器远离SSL证书漏洞侵扰

    TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

  • 相关阅读:
    hihocoder #1467 : 2-SAT·hihoCoder音乐节 2-SAT
    hihoCoder#1185 : 连通性·三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值
    hihoCoder1175 拓扑排序·二 拓扑排序
    012 列表的一些常用操作符
    011,列表2
    010 列表1
    009,分支和循环3
    008,分支和循环2
    006 Python的操作符
    005 Python的数值类型
  • 原文地址:https://www.cnblogs.com/zhuqil/p/1644710.html
Copyright © 2020-2023  润新知