首页 > 编程开发 > Objective-C编程 >
-
WF中的跟踪服务6 如何自定义跟踪服务
在前几篇文章中我们都是围绕这SqlTrackingService这一WF内置的跟踪服务来讲述的。有的时候我们有自己特殊的需求,比如我不想把这个跟踪数据存到Sql数据库中,比如我想把跟踪信息发送到制定的邮件中等。我们这个时候就可以实现自己的跟踪服务。本文我将用最少的代码来实现一个文件跟踪服务,将跟踪信息存到文件中。
开发自定义跟踪服务我们要实现两个类,实现跟踪通道TrackingChannel和跟踪服务TrackingService。 跟踪通道接收运行时发送的跟踪记录。运行时跟踪基础结构使用此跟踪通道将与工作流实例关联的跟踪记录发送回宿主应用程序。应用程序可以采用您选择的任何方式处理此跟踪信息。例如,SqlTrackingService将跟踪信息写入 SQL 数据库。 跟踪服务根据具体参数和条件为运行时提供跟踪配置文件。 它还负责提供可接收运行时所发送数据的跟踪通道。
一:实现Tracking Channel
我们首先实现一个FileTrackingChannel类,代码如下:
public class FileTrackingChannel:TrackingChannel
{
TrackingParameters tPara = null;
StreamWriter streamWriter = File.CreateText("CaryWorkflowTrackLog.txt");
string strWorkflowTrackLog = "";
public FileTrackingChannel(TrackingParameters tPara)
{
this.tPara = tPara;
}
protected override void Send(TrackingRecord record)
{
if (record is WorkflowTrackingRecord)
{
WorkflowTrackingRecord wfRecord= record as WorkflowTrackingRecord;
kflowTrackLog = "工作流实例信息:" + wfRecord.EventDateTime +" "+
wfRecord.TrackingWorkflowEvent;
WriteToFile(strWorkflowTrackLog);
}
if (record is ActivityTrackingRecord)
{
ActivityTrackingRecord actRecord= record as ActivityTrackingRecord;
strWorkflowTrackLog = "活动信息:" + actRecord.EventDateTime + " "+
actRecord.ActivityType.Name;
WriteToFile(strWorkflowTrackLog);
}
if (record is UserTrackingRecord)
{
UserTrackingRecord userRecord= record as UserTrackingRecord;
if (userRecord.UserData is RuleActionTrackingEvent)
{
RuleActionTrackingEvent ruleAction= userRecord.UserData as RuleActionTrackingEvent;
strWorkflowTrackLog = "用户信息:" + userRecord.EventDateTime+" "
+ ruleAction.RuleName
+ ruleAction.ConditionResult;
WriteToFile(strWorkflowTrackLog);
}
else
{
strWorkflowTrackLog = "用户信息:" + userRecord.EventDateTime+" " +
userRecord.UserData;
WriteToFile(strWorkflowTrackLog);
}
}
}
protected override void InstanceCompletedOrTerminated()
{
WriteToFile("log记录完成,ID:"+tPara.InstanceId.ToString());
}
private void WriteToFile(string trackLogContent)
{
streamWriter.AutoFlush = true;
streamWriter.WriteLine(trackLogContent);
}
}
Send方法是两个必须实现抽象方法之一,每当有跟踪数据传递给跟踪服务的时候该方法都会通过工作流引擎被调用。该方法传第一个TrackingRecord参数,可以是三种跟踪记录类型中的任意一种。InstanceCompletedOrTerminated方法是另一个必须实现的方法。该方法在工作流实例完成或终止时被调用。在该类中我们将跟踪信息写到制定的文件中。
二:实现TrackingService
下面我们来实现FileTrackingService类,代码如下:public class FileTrackingService:TrackingService
{
private TrackingProfile defaultProfile;
public FileTrackingService(): base()
{
defaultProfile = GetDefaultProfile();
}
protected override TrackingChannel GetTrackingChannel(TrackingParameters parameters)
{
return new FileTrackingChannel(parameters);
}
protected override TrackingProfile GetProfile(Guid workflowInstanceId)
{
return defaultProfile;
}
protected override TrackingProfile GetProfile(Type workflowType, Version profileVersionId)
{
return defaultProfile;
}
protected override bool TryGetProfile(Type workflowType, out TrackingProfile profile)
{
profile = defaultProfile;
return true;
}
protected override bool TryReloadProfile(Type workflowType, Guid workflowInstanceId,
out TrackingProfile profile)
{
profile = null;
return false;
}
private TrackingProfile GetDefaultProfile()
{
TrackingProfile profile = new TrackingProfile();
WorkflowTrackPoint workflowPoint= new WorkflowTrackPoint();
List<TrackingWorkflowEvent> workflowEvents= new List<TrackingWorkflowEvent>();
workflowEvents.AddRange(Enum.GetValues(typeof(TrackingWorkflowEvent))
as IEnumerable<TrackingWorkflowEvent>);
WorkflowTrackingLocation workflowLocation= new WorkflowTrackingLocation(workflowEvents);
workflowPoint.MatchingLocation = workflowLocation;
profile.WorkflowTrackPoints.Add(workflowPoint);
ActivityTrackPoint activityPoint= new ActivityTrackPoint();
List<ActivityExecutionStatus> activityStatus= new List<ActivityExecutionStatus>();
activityStatus.AddRange(Enum.GetValues(typeof(ActivityExecutionStatus))
as IEnumerable<ActivityExecutionStatus>);
ActivityTrackingLocation activityLocation= new ActivityTrackingLocation(
typeof(Activity), true, activityStatus);
activityPoint.MatchingLocations.Add(activityLocation);
profile.ActivityTrackPoints.Add(activityPoint);
UserTrackPoint userPoint = new UserTrackPoint();
UserTrackingLocation userLocation = new UserTrackingLocation(
typeof(Object), typeof(Activity));
userLocation.MatchDerivedActivityTypes = true;
userLocation.MatchDerivedArgumentTypes = true;
userPoint.MatchingLocations.Add(userLocation);
profile.UserTrackPoints.Add(userPoint);
profile.Version = new Version(1, 0, 0);
return profile;
}
}
自定义的跟踪服务有两个任务。首先是提供Tracking Profiles给工作流引擎。其次他返回一个跟踪管道的实例给工作流引擎。我们找个FileTrackingService是不支持自定义的Tracking Profile的。
三。使用FileTrackingService
我们在宿主程序中将该FileTrackingService添加在WorkflowRuntime中,如下:
FileTrackingService fts = new FileTrackingService();
在工作流中我们放一个CodeActivity,其ExecuteCode事件代码如下:
workflowRuntime.AddService(fts);private void codeActivity1_ExecuteCode(object sender, EventArgs e)
执行工作流结果如下图:
{
Console.WriteLine("codeActivity1执行了!");
TrackData("CaryUserData", "CaryUserDataRecord");
}
我们的跟踪信息已经写入到指定的文件中了,当然我们只是做了最基本的工作。
Send方法是两个必须实现抽象方法之一,每当有跟踪数据传递给跟踪服务的时候该方法都会通过工作流引擎被调用。该方法传第一个TrackingRecord参数,可以是三种跟踪记录类型中的任意一种。InstanceCompletedOrTerminated方法是另一个必须实现的方法。该方法在工作流实例完成或终止时被调用。在该类中我们将跟踪信息写到制定的文件中。
二:实现TrackingService
下面我们来实现FileTrackingService类,代码如下:public class FileTrackingService:TrackingService
{
private TrackingProfile defaultProfile;
public FileTrackingService(): base()
{
defaultProfile = GetDefaultProfile();
}
protected override TrackingChannel GetTrackingChannel(TrackingParameters parameters)
{
return new FileTrackingChannel(parameters);
}
protected override TrackingProfile GetProfile(Guid workflowInstanceId)
{
return defaultProfile;
}
protected override TrackingProfile GetProfile(Type workflowType, Version profileVersionId)
{
return defaultProfile;
}
protected override bool TryGetProfile(Type workflowType, out TrackingProfile profile)
{
profile = defaultProfile;
return true;
}
protected override bool TryReloadProfile(Type workflowType, Guid workflowInstanceId,
out TrackingProfile profile)
{
profile = null;
return false;
}
private TrackingProfile GetDefaultProfile()
{
TrackingProfile profile = new TrackingProfile();
WorkflowTrackPoint workflowPoint= new WorkflowTrackPoint();
List<TrackingWorkflowEvent> workflowEvents= new List<TrackingWorkflowEvent>();
workflowEvents.AddRange(Enum.GetValues(typeof(TrackingWorkflowEvent))
as IEnumerable<TrackingWorkflowEvent>);
WorkflowTrackingLocation workflowLocation= new WorkflowTrackingLocation(workflowEvents);
workflowPoint.MatchingLocation = workflowLocation;
profile.WorkflowTrackPoints.Add(workflowPoint);
ActivityTrackPoint activityPoint= new ActivityTrackPoint();
List<ActivityExecutionStatus> activityStatus= new List<ActivityExecutionStatus>();
activityStatus.AddRange(Enum.GetValues(typeof(ActivityExecutionStatus))
as IEnumerable<ActivityExecutionStatus>);
ActivityTrackingLocation activityLocation= new ActivityTrackingLocation(
typeof(Activity), true, activityStatus);
activityPoint.MatchingLocations.Add(activityLocation);
profile.ActivityTrackPoints.Add(activityPoint);
UserTrackPoint userPoint = new UserTrackPoint();
UserTrackingLocation userLocation = new UserTrackingLocation(
typeof(Object), typeof(Activity));
userLocation.MatchDerivedActivityTypes = true;
userLocation.MatchDerivedArgumentTypes = true;
userPoint.MatchingLocations.Add(userLocation);
profile.UserTrackPoints.Add(userPoint);
profile.Version = new Version(1, 0, 0);
return profile;
}
}
自定义的跟踪服务有两个任务。首先是提供Tracking Profiles给工作流引擎。其次他返回一个跟踪管道的实例给工作流引擎。我们找个FileTrackingService是不支持自定义的Tracking Profile的。
三。使用FileTrackingService
我们在宿主程序中将该FileTrackingService添加在WorkflowRuntime中,如下:
FileTrackingService fts = new FileTrackingService();
在工作流中我们放一个CodeActivity,其ExecuteCode事件代码如下:
workflowRuntime.AddService(fts);private void codeActivity1_ExecuteCode(object sender, EventArgs e)
执行工作流结果如下图:
{
Console.WriteLine("codeActivity1执行了!");
TrackData("CaryUserData", "CaryUserDataRecord");
}
我们的跟踪信息已经写入到指定的文件中了,当然我们只是做了最基本的工作。