Using Custom Activities with Workflow Markup
If you use custom activities in your workflow markup code, the assemblies that contain the activities must be available to the WorkflowRuntime if you are creating a workflow instance from markup, or the workflow compiler if you are compiling the workflow. If you are creating a workflow instance from markup and the custom activity assembly is not registered in the global assembly cache, you can use a TypeProvider to register the assembly with the WorkflowRuntime. In the following example, a custom ConsoleWriteLineActivity
activity is hosted in a markup workflow, the assembly for the ConsoleWriteLineActivity
activity is registered with the WorkflowRuntime and an instance of the workflow is created and executed.
public partial class ConsoleWriteLineActivity :
System.Workflow.ComponentModel.Activity
{
public ConsoleWriteLineActivity()
{
InitializeComponent();
}
public string Msg { get; set; }
protected override ActivityExecutionStatus
Execute(ActivityExecutionContext executionContext)
{
Console.WriteLine(Msg);
return ActivityExecutionStatus.Closed;
}
}
<?xml version="1.0" encoding="utf-16"?>
<SequentialWorkflowActivity x:Name="SequentialWorkflowActivity"
xmlns:ns0="clr-namespace:XamlCodeExamples;Assembly=XamlCodeExamples,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/workflow">
<ns0:ConsoleWriteLineActivity
x:Name="consoleWriteLineActivity1"
Msg="Hello World!" />
</SequentialWorkflowActivity>
// Create a WorkflowRuntime instance.
using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
// Subscribe to desired WorkflowRuntime events.
workflowRuntime.WorkflowCompleted +=
new EventHandler<WorkflowCompletedEventArgs>
(workflowRuntime_WorkflowCompleted);
workflowRuntime.WorkflowTerminated +=
new EventHandler<WorkflowTerminatedEventArgs>
(workflowRuntime_WorkflowTerminated);
// Add the Assembly that contains ConsoleWriteLineActivity
// to a TypeProvider and register the TypeProvider with
// the WorkflowRuntime.
TypeProvider tp = new TypeProvider(workflowRuntime);
tp.AddAssembly(Assembly.LoadFile(assemblyPath));
workflowRuntime.AddService(tp);
// Create the workflow using XAML activation and execute it.
// If there are errors, display them to the Console.
try
{
WorkflowInstance instance = workflowRuntime.CreateWorkflow(reader);
instance.Start();
waitHandle.WaitOne();
}
catch (WorkflowValidationFailedException ex)
{
Console.WriteLine("Exception: {0}", ex.Message);
Console.WriteLine("Errors collection: {0} errors", ex.Errors.Count);
foreach (ValidationError error in ex.Errors)
{
Console.WriteLine(error.ToString());
}
}
If you are compiling the markup workflow with using WorkflowCompiler, you must pass in the path the custom assembly as part of the WorkflowCompilerParameters. For more information, see WorkflowCompiler and WorkflowCompilerParameters.
See Also
Reference
WorkflowCompiler
WorkflowCompilerParameters