编程方式操作WorkFlow

简介:             背景:               刚进某地产公司,就是做一个工作流的小Demo,就是画一条采购的工作流,然后代码实现它。              刚开始的时候真的其实挺迷茫的,然后就从自己比较熟悉的实体做起,接着是controller,然后是view,代码都是参考过N份的,最后代码写的差不多了,然后才开始画一条流程。


           

背景:     

         刚进某地产公司,就是做一个工作流的小Demo,就是画一条采购的工作流,然后代码实现它。



             刚开始的时候真的其实挺迷茫的,然后就从自己比较熟悉的实体做起,接着是controller,然后是view,代码都是参考过N份的,最后代码写的差不多了,然后才开始画一条流程。流程图就画了前后有6份,然后改来改去,委屈还好有各位哥哥帮忙,吐舌头。最后一条流程总算是走了下来。就在上周五的时候,SA突然让我就开始熟悉需求了,没想到这么快就要开始干活了。


   

  

简谈

        

      最开始做工作流的时候,感觉它跟职责链模式很像,它的处理都是一级一级的,尤其是用工作流处理一个大企业的工作流程的时候,必须要定义的非常严格,每一步都要在计划之内,人只是这一步流程上的资源而已。


      做考核项目的时候,是用流程模板设计器做的图,但是考核项目快要做的时候,看到了一个Training Video,,发现居然也能用编程方式编出整个流程。


     虽然编程方式不像可视环境那么舒服,但是学习这种方式操作工作流对于以后我们在编程中控制工作流是很有好处的。



 源码展示



 

 class Program
    {
        static void Main(string[] args)
        {



            #region 编程创建流程——lhc——2015年1月7日14:52:07

                    ////创建一个流程
                    //WfProcessDescriptor process = new WfProcessDescriptor("workFlowTest");
                    //process.Name = "工作流测试";//流程命名


                    ////创建一个首节点
                    //WfActivityDescriptor initActDesp = new WfActivityDescriptor("N0", WfActivityType.InitialActivity);
                    //initActDesp.Name = "这是一个首节点";

                    ////创建一个结束点
                    //WfActivityDescriptor completeActDesp = new WfActivityDescriptor("N1", WfActivityType.CompletedActivity);
                    //completeActDesp.Name = "结束点";

                    //process.Activities.Add(initActDesp); //将首节点加入流程中
                    //process.Activities.Add(completeActDesp);//将尾节点加入流程中


                    // //创建一个正常点
                    //WfActivityDescriptor normalActDesp = new WfActivityDescriptor("N2", WfActivityType.NormalActivity);
                    //normalActDesp.Name = "这是一个比较正常点";


                    ////从授权中心拿人
                    //var  users = OguMechanismFactory.GetMechanism().GetObjects<IUser>(SearchOUIDType.LogOnName, "fanhy");

                    ////加入资源到正常点中
                    //normalActDesp.Resources.Add(new WfUserResourceDescriptor(users[0]));  //加入资源


                    //process.Activities.Add(normalActDesp);//加入到流程集合中


                    ////流程之间的连线
                    ////initActDesp.ToTransitions.AddForwardTransition(completeActDesp); //从起始点加一根向前的线到终结点
                    ////completeActDesp.ToTransitions.AddBackwardTransition(initActDesp);//从终结点加一个到起始点的回去的线

                    //initActDesp.ToTransitions.AddForwardTransition(normalActDesp); //从起点到正常点的连线
                    //normalActDesp.ToTransitions.AddForwardTransition(completeActDesp);//从正常点到终结点的连线

                

                    ////保存流程:从内存到DB
                    //WfProcessDescriptorManager.SaveDescriptor(process);   

                




            #endregion


            #region 读取工作流信息——lhc——2015年1月7日15:33:15

                ////根据名称读取工作流
                //    IWfProcessDescriptor processDesp = WfProcessDescriptorManager.GetDescriptor("workFlowTest");  
                //   // Console.WriteLine(processDesp.Name);//输出工作流名称

                //    EnumActivities(processDesp.InitialActivity);  //打印起点


            #endregion


            #region 启动流程——lhc——2015年1月7日16:25:40



            //////根据名称读取工作流
            //IWfProcessDescriptor processDesp = WfProcessDescriptorManager.GetDescriptor("workFlowTest");

            //WfProcessStartupParams startupParams = new WfProcessStartupParams(); //启动流程的参数

            //startupParams.ProcessDescriptor = processDesp;  //要启动的流程赋值

            ////运行态可以重新定义人(资源),流程设计器里提前配好的资源只是一个默认值
            //startupParams.Assignees.Add(processDesp.InitialActivity.Resources.ToUsers());  //将第一个节点的人抄过来

            //startupParams.ResourceID = UuidHelper.NewUuidString();//UUID赋值

            //IWfProcess process = WfRuntime.StartWorkflow(startupParams);//启动流程


            ////打印
            //Console.WriteLine(process.ID);//流程ID
            //Console.WriteLine(process.Descriptor.Name);//流程描述


            ////////--------在这之前,所有的操作都是在内存中的

            //WfRuntime.PersistWorkflows();//持久化工作流

            //Console.WriteLine(process.ID);//ID


                
            #endregion


            #region 获取运行时流程——lhc——2015年1月7日16:25:49

                ////288926d4-8c53-bdb5-47b1-b655d002b1e7

                //IWfProcess processStart = WfRuntime.GetProcessByProcessID("288926d4-8c53-bdb5-47b1-b655d002b1e7");

                ////Console.WriteLine();
                //Console.WriteLine(processStart.CurrentActivity.Descriptor.Name);//获取当前节点名称
            


            //TODO:没有找到UserTaskAdapter
               // UserTaskCollection tasks = UserTaskAdapter.Instance.LoadUserTasks(builder => builder.AppendItem("Activity_id",processStart .CurrentActivity .ID)); //
                //Console.WriteLine(task.count);//输出数量
                

            

                
            
            #endregion



            #region 流程的流转——lhc——2015年1月7日16:25:59

               // IWfProcess processStart = WfRuntime.GetProcessByProcessID("288926d4-8c53-bdb5-47b1-b655d002b1e7");


               // //找到起始点的下一个结点
               // IWfActivityDescriptor targetActDesp = processStart.InitialActivity.Descriptor.ToTransitions[0].ToActivity;


               // //流转参数
               // WfTransferParams transferParams = new WfTransferParams(targetActDesp);

               // transferParams.Assignees.Add(targetActDesp.Resources.ToUsers());  //加入资源

               // processStart.MoveTo(transferParams);  //从第一个节点流转到下一个








               // //流程上下文
               ////WfRuntime.ProcessContext 

               // //处理挂起的流程——一个流程只能有一个处于挂起的
               // //WfRuntime.ProcessPendingActivity();
               //         //等待一个外部条件

               // //


               // processStart.ApplicationRumtimeParameters["Data"] = "lhc";//流程参数赋值,但是WfRuntime.PersistWorkflows(); 不能被此条语句保存



               // //强制保存的语句——important
               // //一般经过方法调用流程的都不用这句话。
               // WfRuntime.ProcessContext.AffectedProcesses.AddOrReplace(processStart );//请执行保存





               // //将内存中的操作持久化到数据库
               // WfRuntime.PersistWorkflows(); //moveto这种大改动可以被此条语句保存
            
            
               // Console.WriteLine(processStart.CurrentActivity.Descriptor.Name);  //打印出当前节点名称

                


                    

            #endregion



            #region executor启动流程——lhc——2015年1月7日21:49:53

                //流程启动参数
                WfProcessStartupParams startupParams = new WfProcessStartupParams();

                //获取要启动流程
                startupParams.ProcessDescriptor = WfProcessDescriptorManager.GetDescriptor("workFlowTest");



                startupParams .ResourceID =UuidHelper .NewUuidString ();//流程GUID赋值


                //加入资源
                startupParams.Assignees.Add(startupParams.ProcessDescriptor.InitialActivity.Resources.ToUsers());

                WfStartWorkflowExecutor executor = new WfStartWorkflowExecutor(null, startupParams);//使用executor启动流程


            //改变标题——加入委托方法
                executor.PrepareMoveToTasks += new PrepareTasksEventHandler(executor_PrepareMoveToTasks);

              IWfProcess process=  executor.Execute();//执行

              Console.WriteLine(process .ID);//输出流程ID


            #endregion


        }



        #region executor启动流程上搭载的方法——lhc——2015年1月7日21:50:11

            private static void executor_PrepareMoveToTasks(WfExecutorDataContext dataContext, MCS.Library.SOA.DataObjects.UserTaskCollection tasks)
            {
                tasks.ForEach(t => t.TaskTitle = "lhc");

            }
        
        #endregion

        #region 根据节点深度遍历流程

              //foreach打印流程名称
        //private static void EnumActivities(IWfActivityDescriptor astDesp)
        //{
        //    Console.WriteLine(astDesp.Name);  //打印节点名称

        //    astDesp.Resources.ToUsers().ForEach(u => Console.WriteLine(u.DisplayName));  //foreach打印节点资源名称

        //    if (astDesp.ActivityType !=WfActivityType .CompletedActivity)
        //    {
        //        //每个节点都有两端,fromActivity和toActivity;
        //        //深度遍历搜索
        //            astDesp.ToTransitions.ForEach(t => EnumActivities(t.ToActivity));

        //    }
        //}
        #endregion
        
		 
	
    }

 

PS:       为了使用操作工作流的各种对象,还要引入一些平台封装的类库什么的




小结

             感觉在程序中,所有的东西都是为一整条流程服务的,就连人也变成了资源依附在流程上,就像这里所提倡的,人依附于事的思想。

          
















          

目录
相关文章
|
6月前
|
API
工作流JBPM操作API删除流程&部署流程
工作流JBPM操作API删除流程&部署流程
43 0
|
数据可视化
2分钟快速上手工作流的创建与运行
2分钟快速上手工作流的创建与运行
103 0
|
存储 负载均衡 中间件
Go 简单实现多租户设计
在 SaaS 系统中多租户是一个很重要的架构,在服务上仅需运行一个软件实例就能够支持每个租户的功能,它们之间的数据互相隔离。就比如 Gitee ,每个用户或组织都拥有自己的空间。它们自己的数据仅在自己的空间内流通,彼此之间互不影响。多租户其实就是一种软件设计结构。 所以。租户模型其实就是分离数据的方式: • 单租户:一个应用一个数据库。其实就是应用分离,数据分离。 • 多租户:一个应用多个数据库。就是同一个应用不同数据库。
797 0
|
Java 数据库连接
JBPM学习(一):实现一个简单的工作流例子全过程
本文主要讲实现一个简单的工作流例子全过程
364 0
JBPM学习(一):实现一个简单的工作流例子全过程
EMQ
|
SQL 传感器 JSON
eKuiper Newsletter 2022-07|v1.6.0:Flow 编排 + 更好用的 SQL,轻松表达业务逻辑
eKuiper本年度第二个大版本 v1.6.0正式发布,面向Flow编排的图规则API已开发完成,同时达成了多个SQL语法和函数的提升,期望覆盖更多样的使用场景,帮助用户进一步减少定制开发的需求和成本。
EMQ
310 0
eKuiper Newsletter 2022-07|v1.6.0:Flow 编排 + 更好用的 SQL,轻松表达业务逻辑
|
XML Java Unix
不了解工作流框架 Activiti 中的流程事件?这篇工作流流程元素详解,带你详细分析工作流流程执行过程中的各种事件
本文介绍了工作流Activiti框架中BPMN结构中各种事件。主要包括定时器事件,错误事件,信号事件,消息事件,开始事件,结束事件,边界事件,中间捕获事件以及内部触发事件。通过对BPMN中各种事件的学习了解,可以帮助我们在项目中更加方便地对工作流中各种处理流程进行应用,极大提高了项目的开发效能。
1053 0
不了解工作流框架 Activiti 中的流程事件?这篇工作流流程元素详解,带你详细分析工作流流程执行过程中的各种事件
|
存储 SQL XML
工作流引擎Activiti使用进阶!详细解析工作流框架中高级功能的使用示例
本篇文章介绍了Activiti的几个高级用例。主要包括监听流程解析,使用UUID生成器,多租户,执行自定义的SQL,实现流程引擎配置,安全的BPMN 2.0结构以及事件日志的使用。使用这些高级功能,可以使得集成工作流Activiti的项目具有更多的可操作性。
1204 0
工作流引擎Activiti使用进阶!详细解析工作流框架中高级功能的使用示例