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,  null null ));
        }

        
// 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, 
null null null );
                }
                
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 {  get set ; }

        
//  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注入漏洞检测。

转载于:https://www.cnblogs.com/zhuqil/archive/2010/01/12/1644710.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值