1、在设计Workflow时,我们用到了HandleExternalEventActivity和CallExternalMethodActivity,它们引用了ILeaveInterface。因此我们需要实现这个Interface中的事件和方法。
在Eallies.OA.Workflow.Handler项目中添加一个Class类,并让其继承与ILeaveInterface。
2、外部程序与Workflow的交互有两个场合,一个是CreateWorkflow时,另一个是处理外部事件时。由于Workflow的等待状态可能持续很长时间,甚至中间可能重新启动了机器,因此这两个场合都需要重新建立Workflow运行的环境。
同时,由于重新启动了机器,内存中的Workflow实例就会丢失。为了防止实例丢失,我们需要将Workflow的实例持久化到数据库中。为了实现这点,可以在Workflow运行时环境中加入SqlWorkflowPersistenceService服务,并设置一旦Workflow空闲了,则持久化到数据库中。
上面的代码中,由于WorkflowRuntime只允许一个实例,且不应该丢失,因此我们采用静态变量的方式保存。
3、由于上述方法都是静态方法,调用起来就非常简单。
4、上述代码继承于ILeaveContract,是WCF技术中的契约部分,然后我们只需要在Eallies.OA.Workflow.Service.Host项目中加入一个SVC项目,即可实现把Workflow给Host到IIS中了。
在Eallies.OA.Workflow.Handler项目中添加一个Class类,并让其继承与ILeaveInterface。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using Eallies.OA.Workflow.Args;
6 using Eallies.OA.Workflow.Interface;
7 using Eallies.OA.Info;
8 using Eallies.OA.Info.Enum;
9 using Eallies.OA.Service.Wrapper;
10
11 namespace Eallies.OA.Workflow.Handler
12 {
13 public class LeaveHandler : ILeaveInterface
14 {
15 #region ILeaveInterface Members
16
17 public event EventHandler<LeaveArgs> LeaveApprove;
18
19 public void UpdateLeaveApproverByLeaveId(int leaveId, int leaveApprover)
20 {
21 LeaveContractClient client = new LeaveContractClient();
22
23 try
24 {
25 client.UpdateLeaveApproverByLeaveId(leaveId, leaveApprover);
26 }
27 catch
28 {
29 throw;
30 }
31 finally
32 {
33 client.Close();
34 }
35 }
36
37 public void UpdateLeaveStatusByLeaveId(int leaveId, LeaveStatusEnum leaveStatus)
38 {
39 LeaveContractClient client = new LeaveContractClient();
40
41 try
42 {
43 client.UpdateLeaveStatusByLeaveId(leaveId, leaveStatus);
44 }
45 catch
46 {
47 throw;
48 }
49 finally
50 {
51 client.Close();
52 }
53 }
54
55 #endregion
56
57 public void RaiseLeaveApprove(Guid instanceId, LeaveApproveResultEnum leaveApproveResult, EmployeeInfo employeeInfo)
58 {
59 try
60 {
61 if (this.LeaveApprove != null)
62 {
63 this.LeaveApprove(null, new LeaveArgs(instanceId, leaveApproveResult, employeeInfo));
64 }
65 }
66 catch
67 {
68 throw;
69 }
70 }
71 }
72 }
同时,由于重新启动了机器,内存中的Workflow实例就会丢失。为了防止实例丢失,我们需要将Workflow的实例持久化到数据库中。为了实现这点,可以在Workflow运行时环境中加入SqlWorkflowPersistenceService服务,并设置一旦Workflow空闲了,则持久化到数据库中。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Web.Configuration;
6 using System.Workflow.Runtime;
7 using System.Workflow.Runtime.Hosting;
8 using System.Workflow.Activities;
9 using System.Collections;
10
11 namespace Eallies.OA.Workflow.Service
12 {
13 public class Factory
14 {
15 private static string _ConnectionString = WebConfigurationManager.ConnectionStrings["Eallies.OA.Workflow"].ConnectionString;
16 private static WorkflowRuntime _WorkflowRuntime = null;
17 private static WorkflowInstance _WorkflowInstance = null;
18 private static ExternalDataExchangeService _ExternalDataExchangeService = null;
19 private static object _Lock = new object();
20
21 public static Guid CreateWorkflow<TWorkflow, THandler>(Dictionary<string, object> parameters)
22 {
23 try
24 {
25 lock (_Lock)
26 {
27 GetWorkflowRuntime();
28
29 _WorkflowInstance = _WorkflowRuntime.CreateWorkflow(typeof(TWorkflow), parameters);
30
31 if (_ExternalDataExchangeService == null)
32 {
33 _ExternalDataExchangeService = new ExternalDataExchangeService();
34
35 _WorkflowRuntime.AddService(_ExternalDataExchangeService);
36 }
37
38 if (_ExternalDataExchangeService.GetService(typeof(THandler)) == null)
39 {
40 _ExternalDataExchangeService.AddService((THandler)Activator.CreateInstance(typeof(THandler)));
41 }
42
43 _WorkflowInstance.Start();
44 }
45
46 return _WorkflowInstance.InstanceId;
47 }
48 catch
49 {
50 throw;
51 }
52 }
53
54 public static T GetHandler<T>(Guid instanceId)
55 {
56 try
57 {
58 lock (_Lock)
59 {
60 GetWorkflowRuntime();
61
62 _WorkflowInstance = _WorkflowRuntime.GetWorkflow(instanceId);
63
64 if (_ExternalDataExchangeService == null)
65 {
66 _ExternalDataExchangeService = new ExternalDataExchangeService();
67
68 _WorkflowRuntime.AddService(_ExternalDataExchangeService);
69 }
70
71 if (_ExternalDataExchangeService.GetService(typeof(T)) == null)
72 {
73 _ExternalDataExchangeService.AddService((T)Activator.CreateInstance(typeof(T)));
74 }
75
76 return (T)_ExternalDataExchangeService.GetService(typeof(T));
77 }
78 }
79 catch
80 {
81 throw;
82 }
83 }
84
85 public static void GetWorkflowRuntime()
86 {
87 try
88 {
89 lock (_Lock)
90 {
91 if (_WorkflowRuntime == null)
92 {
93 AppDomain.CurrentDomain.ProcessExit += new EventHandler(StopWorkflowRuntime);
94 AppDomain.CurrentDomain.DomainUnload += new EventHandler(StopWorkflowRuntime);
95
96 _WorkflowRuntime = new WorkflowRuntime();
97
98 _WorkflowRuntime.AddService(new SqlWorkflowPersistenceService(_ConnectionString, true, new TimeSpan(0, 0, 0, 10, 0), new TimeSpan(0, 0, 0, 10, 0)));
99
100 _WorkflowRuntime.StartRuntime();
101 }
102 }
103 }
104 catch
105 {
106 throw;
107 }
108 }
109
110 private static void StopWorkflowRuntime(object sender, EventArgs e)
111 {
112 try
113 {
114 if (_WorkflowRuntime != null)
115 {
116 if (_WorkflowRuntime.IsStarted == true)
117 {
118 _WorkflowRuntime.StopRuntime();
119 }
120 }
121 }
122 catch
123 {
124 throw;
125 }
126 }
127 }
128 }
3、由于上述方法都是静态方法,调用起来就非常简单。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Workflow.Runtime;
6 using System.Workflow.Activities;
7 using Eallies.OA.Workflow;
8 using Eallies.OA.Workflow.Args;
9 using Eallies.OA.Workflow.Handler;
10 using Eallies.OA.Workflow.Service.Contract;
11 using Eallies.OA.Info;
12 using Eallies.OA.Info.Enum;
13
14 namespace Eallies.OA.Workflow.Service
15 {
16 public class LeaveService : ILeaveContract
17 {
18 #region ILeaveContract Members
19
20 public Guid CreateWorkflow(int leaveId, EmployeeInfo employeeInfo)
21 {
22 try
23 {
24 Dictionary<string, object> parameters = new Dictionary<string, object>();
25 parameters.Add("LeaveId", leaveId);
26 parameters.Add("EmployeeInfo", employeeInfo);
27
28 return Factory.CreateWorkflow<LeaveWorkflow, LeaveHandler>(parameters);
29 }
30 catch
31 {
32 throw;
33 }
34 }
35
36 public void LeaveApprove(Guid instanceId, LeaveApproveResultEnum leaveApproveResult, EmployeeInfo employeeInfo)
37 {
38 try
39 {
40 Factory.GetHandler<LeaveHandler>(instanceId).RaiseLeaveApprove(instanceId, leaveApproveResult, employeeInfo);
41 }
42 catch
43 {
44 throw;
45 }
46 }
47
48 #endregion
49 }
50 }
1 <%@ ServiceHost Language="C#" Debug="true" Service="Eallies.OA.Workflow.Service.LeaveService" %>
本文转自 Eallies 51CTO博客,原文链接:http://blog.51cto.com/eallies/79047,如需转载请自行联系原作者