using System;
using System.Collections.Generic;
using System.Text;
using System.Workflow.Runtime.Hosting;
using System.Workflow.Runtime;
using System.Diagnostics;
using System.Collections.Specialized;
namespace WFServices
{
// Define the delegate that will be used when writing output
internal delegate void WriterDelegate ( string output );
///
/// This service is designed to output all events raised by the workflow runtime to the Debug log
///
public class RuntimeEventWriter : WorkflowRuntimeService
{
///
/// Construct the object and decide which writer(s) we're going to use
///
///
public RuntimeEventWriter(NameValueCollection args)
{
// Create an empty delegate just in case the user has not supplied any parameters
_writers = new WriterDelegate(WriteNowhere);
if (args["Console"] == "true")
_writers = (WriterDelegate)Delegate.Combine(_writers, new WriterDelegate(WriteToConsole));
if ( args["Trace"] == "true")
_writers = (WriterDelegate)Delegate.Combine(_writers, new WriterDelegate(WriteToTrace));
if (args["Debug"] == "true")
_writers = (WriterDelegate)Delegate.Combine(_writers, new WriterDelegate(WriteToDebug));
}
///
/// Hook all runtime events
///
protected override void OnStarted()
{
Runtime.WorkflowAborted += new EventHandler(OnWorkflowAborted);
Runtime.WorkflowCompleted += new EventHandler(OnWorkflowCompleted);
Runtime.WorkflowCreated += new EventHandler(OnWorkflowCreated);
Runtime.WorkflowIdled += new EventHandler(OnWorkflowIdled);
Runtime.WorkflowLoaded += new EventHandler(OnWorkflowLoaded);
Runtime.WorkflowPersisted += new EventHandler(OnWorkflowPersisted);
Runtime.WorkflowResumed += new EventHandler(OnWorkflowResumed);
Runtime.WorkflowStarted += new EventHandler(OnWorkflowStarted);
Runtime.WorkflowSuspended += new EventHandler(OnWorkflowSuspended);
Runtime.WorkflowTerminated += new EventHandler(OnWorkflowTerminated);
Runtime.WorkflowUnloaded += new EventHandler(OnWorkflowUnloaded);
}
///
/// Unhook all runtime events
///
protected override void OnStopped()
{
Runtime.WorkflowAborted -= new EventHandler(OnWorkflowAborted);
Runtime.WorkflowCompleted -= new EventHandler(OnWorkflowCompleted);
Runtime.WorkflowCreated -= new EventHandler(OnWorkflowCreated);
Runtime.WorkflowIdled -= new EventHandler(OnWorkflowIdled);
Runtime.WorkflowLoaded -= new EventHandler(OnWorkflowLoaded);
Runtime.WorkflowPersisted += new EventHandler(OnWorkflowPersisted);
Runtime.WorkflowResumed -= new EventHandler(OnWorkflowResumed);
Runtime.WorkflowStarted -= new EventHandler(OnWorkflowStarted);
Runtime.WorkflowSuspended -= new EventHandler(OnWorkflowSuspended);
Runtime.WorkflowTerminated -= new EventHandler(OnWorkflowTerminated);
Runtime.WorkflowUnloaded -= new EventHandler(OnWorkflowUnloaded);
}
void OnWorkflowUnloaded(object sender, WorkflowEventArgs e)
{
_writers.Invoke (string.Format("Workflow {0} Unloaded at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
{
_writers.Invoke (string.Format("Workflow {0} Terminated at {1}.\r\n Exception was '{2}'.\r\n{3}", e.WorkflowInstance.InstanceId, DateTime.Now, e.Exception.Message, e.Exception.StackTrace));
}
void OnWorkflowSuspended(object sender, WorkflowSuspendedEventArgs e)
{
if ( string.IsNullOrEmpty ( e.Error) )
_writers.Invoke(string.Format("Workflow {0} Suspended at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
else
_writers.Invoke(string.Format("Workflow {0} Suspended with error at {1}.\r\n Error was '{2}'.", e.WorkflowInstance.InstanceId, DateTime.Now, e.Error));
}
void OnWorkflowStarted(object sender, WorkflowEventArgs e)
{
_writers.Invoke(string.Format("Workflow {0} Started at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
void OnWorkflowResumed(object sender, WorkflowEventArgs e)
{
_writers.Invoke(string.Format("Workflow {0} Resumed at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
void OnWorkflowPersisted(object sender, WorkflowEventArgs e)
{
_writers.Invoke(string.Format("Workflow {0} Persisted at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
void OnWorkflowLoaded(object sender, WorkflowEventArgs e)
{
_writers.Invoke(string.Format("Workflow {0} Loaded at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
void OnWorkflowIdled(object sender, WorkflowEventArgs e)
{
_writers.Invoke(string.Format("Workflow {0} Idled at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
void OnWorkflowCreated(object sender, WorkflowEventArgs e)
{
_writers.Invoke(string.Format("Workflow {0} Created at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair kvp in e.OutputParameters)
{
sb.AppendFormat(" {0} = {1}\r\n", kvp.Key, (kvp.Value == null) ? "null" : kvp.Value );
}
_writers.Invoke(string.Format("Workflow {0} Completed at {1}.\r\n Output Parameters were...\r\n{2}", e.WorkflowInstance.InstanceId, DateTime.Now, sb.ToString()));
}
void OnWorkflowAborted(object sender, WorkflowEventArgs e)
{
Debug.WriteLine(string.Format("Workflow {0} Aborted at {1}.", e.WorkflowInstance.InstanceId, DateTime.Now));
}
///
/// Write the text to the console
///
///
void WriteToConsole(string text)
{
Console.WriteLine(text);
}
///
/// Write the text to the debug stream
///
///
void WriteToDebug(string text)
{
Debug.WriteLine(text);
}
///
/// Write the text to the trace stream
///
///
void WriteToTrace(string text)
{
Trace.WriteLine(text);
}
///
/// Don't write the text anywhere
///
///
void WriteNowhere(string text)
{
}
///
/// Delegate used to output data to the console/debug/trace
///
private WriterDelegate _writers;
}
}