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,如需转载请自行联系原作者