This post contains one very simple working example of the WorkflowPersistenceService which persist workflow instances in the
file store.
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Workflow.Runtime.Hosting;
using
System.Workflow.ComponentModel;
using
System.IO;
using
System.Workflow.Runtime;
using
System.Diagnostics;
namespace
Daenet.Workflow
{
/// <summary>
/// Implements the custom
WorkflowPersistenceService, which persists workflow instances in the file.
/// </summary>
public class WFFilePersistenceProvider
: WorkflowPersistenceService
{
/// <summary>
///
/// </summary>
/// <param name="folder">The folder where the instance will be persisted.</param>
public
WFFilePersistenceProvider(string folder)
{
m_Folder = folder;
if (Directory.Exists(folder) == false)
Directory.CreateDirectory(folder);
}
private string m_Folder = "WFPersistance";
#region Serialization
/// <summary>
/// Performs the
serialization of one activity. Invoked during dehydration.
/// </summary>
/// <param name="RootActivity"></param>
/// <param name="id"></param>
private void SerializeActivity(Activity RootActivity, Guid id)
{
string filename = getFileName(ref id);
lock (typeof(WFFilePersistenceProvider))
{
using (FileStream stream = new FileStream(filename, FileMode.OpenOrCreate))
{
RootActivity.Save(stream);
}
}
}
/// <summary>
/// Performs
deserialization of persisted activity. Invoked during rehydration.
/// </summary>
/// <param name="RootActivity"></param>
/// <param name="id"></param>
/// <returns></returns>
private object DeserializeActivity(Activity RootActivity, Guid id)
{
string filename = getFileName(ref id);
lock (typeof(WFFilePersistenceProvider))
{
using (FileStream stream = new FileStream(filename, FileMode.Open))
{
object Result = Activity.Load(stream,
RootActivity);
return Result;
}
}
}
#endregion
#region Private Members
private string getFileName(ref Guid id)
{
string filename = m_Folder + "\\" + id.ToString() + ".wf";
return filename;
}
private Guid getIdFromFileName(string fileName)
{
int pos = fileName.LastIndexOf("\\");
if (pos == -1)
throw new ApplicationException("Serialization in
the root is not
supported. Please specify the folder which will contain
persisted files.");
string guidStr = fileName.Substring(pos + 1, fileName.Length - 4 - pos);
return new Guid(guidStr);
}
#endregion
#region Provider Members
#region WorkflowProvider Interface Implementation
protected override
System.Workflow.ComponentModel.Activity
LoadCompletedContextActivity(Guid scopeId,
System.Workflow.ComponentModel.Activity outerActivity)
{
Trace.WriteLine("Rehydration");
object obj = DeserializeActivity(outerActivity, scopeId);
return (Activity)obj;
}
protected override
System.Workflow.ComponentModel.Activity LoadWorkflowInstanceState(Guid instanceId)
{
Trace.WriteLine("Rehydration");
object obj = DeserializeActivity(null, instanceId);
return (Activity)obj;
}
protected override void
SaveCompletedContextActivity(System.Workflow.ComponentModel.Activity activity)
{
Guid contextGuid = (Guid)activity.GetValue(Activity.ActivityContextGuidProperty);
SerializeActivity(activity, contextGuid);
}
protected override void
SaveWorkflowInstanceState
(System.Workflow.ComponentModel.Activity rootActivity, bool unlock)
{
// Remove this
"if" statement, if you want to persist workflow in any status.
if (rootActivity.ExecutionStatus == ActivityExecutionStatus.Executing)
{
Guid contextGuid = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);
SerializeActivity(rootActivity,
contextGuid);
}
}
protected override bool
UnloadOnIdle(System.Workflow.ComponentModel.Activity activity)
{
return false;
}
protected override void
UnlockWorkflowInstanceState(System.Workflow.ComponentModel.Activity rootActivity)
{
}
#endregion
public void PersistWorkflow(WorkflowInstance
wInstance)
{
Activity rootActivity = wInstance.GetWorkflowDefinition();
SaveWorkflowInstanceState(rootActivity, true);
}
/// <summary>
/// This method traverses
all serializaed wirkflow instances and loads Loads
/// persisted workflows.
/// </summary>
/// <returns></returns>
public ICollection<WorkflowInstance>
LoadPersistedWorkflows()
{
List<WorkflowInstance> persistedWorkflows = new List<WorkflowInstance>();
string[] files = Directory.GetFiles(m_Folder, "*.wf");
foreach (string file in files)
{
Guid id = getIdFromFileName(file);
persistedWorkflows.Add(this.Runtime.GetWorkflow(id));
}
return persistedWorkflows;
}
/// <summary>
/// Deletes all existing
serialized files. After this call no workflow remains in the store.
/// </summary>
public void Clean()
{
string[] files = Directory.GetFiles(m_Folder, "*.wf");
foreach (string file in files)
{
File.Delete(file);
}
}
#endregion
}
}
This code snippet shows how to programmatically add the
custom workflow persistence service:
WFFilePersistenceProvider persistanceService = new WFFilePersistenceProvider("c:\\temp\\WFPersistance");
WorkflowRuntime runtime = new WorkflowRuntime();
runtime.AddService(persistanceService);
Posted
Aug 29 2007, 10:35 AM
by
Damir Dobric