标签:
从面向对象到面向服务,接触到的理念越来越多,视野也在逐渐扩大,对面向对象这种理念的感觉似乎也在一天天发生着很多不同的变化。很多原来没想过的,现在大家都在开始去讨论它们具体的实现了,看来真是学无止境啊!
接触到SOA这个理念其实已经有一段时间了,面向服务,针对于编程中的组件,模块或者说功能单元,为它们提供接口和服务。是对面向对象思想的一种补充。我们用到的WCF也是基于此思想实现的。
而工作流(Workflow),指“业务过程的部分或整体在计算机应用环境下的自动化。工作流主要解决的主要问题是:为了实现某个业务目标,利用计算机在多个参与者之间按某种预定规则自动传递文档、信息或者任务。
其实这里看到的吸引人的还是‘自动化’这个词,从这里看出,应用工作流,我们可以让我们开发出来的软件根据需求自动实现自己的功能,最大程度上脱离人工操作或后台代码的编写。
其中状态机工作流是开发中最常用的也是功能最强大的一种。
1、通过invoke的方式,在启动的主线程中启动相应的工作流
Activity activity = newDocActivity ();
WorkflowInvoker.Invoke(activity);
2、微软提供的一种application操作
在工作流中,通过书签来使工作流能够停下来去接收一些参数或具体的操作等。
如何能更好的实现自动化,在用户审批或者中间进行其他相应操作时,能不限定时间,或者更加方便,这就用到了WF持久化。
WF持久化SQL: .NET Framework 4.5安装程序将与 SQL 工作流实例存储功能相关联的 SQL脚本文件复制到 %WINDIR%\Microsoft.NET\Framework\v4.xxx\SQL\EN文件夹。 SQL 工作流实例存储用于持久保存工作流实例的 SQL Server 2005或SQL Server 2008 数据库,运行这些脚本文件。 首先运行 SqlWorkflowInstanceStoreSchema.sql文件,然后运行 SqlWorkflowInstanceStoreLogic.sql文件。
通过以上操作就可以建立好WF持久化SQL的数据库了。利用持久化技术,用户审批工作的时候,就可以随时根据自己的安排来进行了。持久化数据库会将系统的当前状态完全重现在用户面前。
最常见的应用工作流的例子:请假审批。当一个申请者提交申请后,工作流会自动将申请提交给指定的审批人,进行具体的审批操作,然后在决定是否继续流转。下面这段代码会将上面涉及到所有关上面说到的WF的基础
总体流程设计如下图:
从start开始进入工作流开始到状态1为止,整个小demo中声明了一个num的变量,T1:条件1如果Num大于5,那么直接进入结束状态,T2:条件2如果Num小于5,那么返回状态1,重新审批。
里面用到的是一个顺序流,InputName为参数。wait4InputActivity为创建的一个代码活动,具体实现如下;
public sealed class wait4InputActivity : NativeActivity //NativeActivity允许创建书签 { // 定义一个字符串类型的活动输入参数 public InArgument<string> BookMarkName { get; set; } public OutArgument<int> Num { get; set; } protected override bool CanInduceIdle { get { return true ; } } // 如果活动返回值,则从 CodeActivity<TResult> // 派生并从 Execute 方法返回该值。 protected override void Execute(NativeActivityContext context) { // 获取 Text 输入参数的运行时值 //string text = context.GetValue(this.Text); string name = context.GetValue(BookMarkName); //创建书签,这时,工作流会空闲下来,这时会进行持久化工作 context.CreateBookmark(name,new BookmarkCallback (ContinueExcuteWorkFlow)); } //object:value值,是当我们让工作流继续往下执行的时候,传来的参数 private void ContinueExcuteWorkFlow(NativeActivityContext context, Bookmark bookmark, object value) { //当我们调用了工作流一个方法让工作流继续往下执行的时候,首先执行此方法 context.SetValue(Num,(int)value); } }
public static class WorkflowApplicationHelper { //通过配置文件链接WF持久化数据库 public static string WorkFlowSqlconn; static WorkflowApplicationHelper() { WorkFlowSqlconn = ConfigurationManager.AppSettings["SqlWorkflowInstanceStore"]; } //创建工作流实例,并且执行之 public static WorkflowApplication CreateHttpApplicationAndRun(Activity activity,IDictionary <string,object> inputs) {
//利用application来控制工作流 WorkflowApplication application = new WorkflowApplication(activity,inputs); //创建工作流序列化需要的SQL序列化对象 SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(WorkFlowSqlconn); //使得当前application对象的实例关联期创建的实例 application.InstanceStore = store; application.OnUnhandledException += m => { Console.WriteLine("工作流出现了未处理的异常"); return UnhandledExceptionAction.Terminate; }; application.Unloaded += m => { Console.WriteLine("工作流卸载!"); }; application.PersistableIdle += a => { Console.WriteLine("工作流进行序列化!"); return PersistableIdleAction.Unload; }; application.Aborted += ea => { Console.WriteLine("工作流崩了!"); }; application.Idle += m => { Console.WriteLine("工作流空闲下来了"); }; application.Run(); return application ; } public static WorkflowApplication LoadWorkFlowApplication(Activity activity,Guid id) { WorkflowApplication application = new WorkflowApplication( activity); //这里不需要再传参数了 //创建工作流序列化需要的SQL序列化对象 SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(WorkFlowSqlconn); //使得当前application对象的实例关联期创建的实例 application.InstanceStore = store; application.OnUnhandledException += m => { Console.WriteLine("工作流出现了未处理的异常"); return UnhandledExceptionAction.Terminate; }; application.Unloaded += m => { Console.WriteLine("工作流卸载!"); }; application.PersistableIdle += a => { Console.WriteLine("工作流进行序列化!"); return PersistableIdleAction.Unload; }; application.Aborted += ea => { Console.WriteLine("工作流强制退出了!"); }; application.Idle += m => { Console.WriteLine("工作流空闲下来了"); }; //从数据库中加载application状态 application.Load(id); return application; } }那么在启动工作流时,只需要:
var inputs= new Dictionary<string, object>() { {"InputName",DateTime .Now .ToString ()}, { "TempBookMarkName",this.txtBookMark .Text }}; WorkflowApplication application =WorkflowApplicationHelper .CreateHttpApplicationAndRun (new DocActivity (),inputs); txtID .Text=application .Id .ToString ();//记录application的id此时,在调用helper时,会将工作流实例的当前状态存储到持久化数据库中去。如果我们关闭程序,在打开时,点击恢复书签时,将保存的id赋给application对象,还会执行原来被保存的实例。
恢复书签:
<span style="white-space:pre"> </span>WorkflowApplication application=WorkflowApplicationHelper.LoadWorkFlowApplication(new DocActivity (),Guid.Parse (txtID .Text )); application.ResumeBookmark(this.txtBookMark.Text, int.Parse(txtNum.Text));经过以上步骤,工作流持久化就完成了。根据这个原理,我们可以利用工作流持久化来完成很多诸如审批这样跨越时间的实际性的工作。确实是很强大的一种思想。
那么以上也只是关于WF的一个小小的实例,如何把WF真正应用到开发中,还需要不断的研究,比如WF如何与泛型结合才能最大程度的抽象,WF内部有很多方法利用委托来实现,那么在业务上如何与委托去结合使用才能更大程度的发挥它强大的面向服务的力量呢,还是值得我们去再进一步讨论的。
标签:
原文地址:http://blog.csdn.net/wangyy130/article/details/44179381