Load Workflow from XML file in Workflow Foundation


The other day I had to use Windows Workflow Foundation in legacy .NET 3.5. The goal was to address the scenario where the power user may upload valid XML files … in an Enterprise Application for different workflows, In other words to avoid hard coding the workflow activities in C# code. So I had to essentially address 2 objectives :

  1. The workflow should be loaded dynamically on the fly
  2. There might be more than one workflows.

So I came up a simple design where the power user may upload a XML file and may give nick names … basically a mini XML file management. Then in the Workflow management module I wrote down something not too different from the following C# code : Let’s start with a simple custom activity

Code Activity is great for a proof of concept or demos but here in WF 3, I think Custom Activity is better than just the code activities, because not only one may parameter-ize them but also they could be reused. I think you’d agree too, at the end of this quick blog post.

So, I had to use Visual Studio 2008 to modify this legacy application but you may use the latest-n-greatest ( and my favorite ) Visual Studio 2013 too ! … Or you want to exactly follow along change the .NET version to 3.5. ( I shall write another blog post for newer version of .NET 4.0 or 4.5 … I promise ! ) For this blog post demo, I started with basic Console Application, named it “WorkflowConsoleApplication3” and then added a new project called “WorkflowProject1” using the Empty Workflow Project Template. Like So : I’ve posted how Program.cs looks like for the console application at the end as it was untouched until end. Next, in the Work Flow Project that we created above, let’s add a new class called “WriteLine”. This is going to be our activity. So let’s inherit this class from System.Workflow.ComponentModel.Activity and make couple other changes as shown below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.ComponentModel;

namespace WorkflowProject1
{
  public class WriteLine : Activity
  {
    public string Text { get; set; }
    public ConsoleColor TextColor { get; set; }

    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
      Console.ForegroundColor = TextColor;
      Console.WriteLine(Text);
      Console.ResetColor();

      return ActivityExecutionStatus.Closed;
    }
  }
}

Feel free to add such few other activities of your choice ( Like exporting some data to file, sending emails etc. ) in the same project or may be in the different project. Alright now you’re ready to create XML workflow definition ! So lets get back to the console application called “WorkflowConsoleApplication3” that we created in the beginning and let’s add XML file from ‘add new item’ window using Visual Studio. ( Did not worry to change the name from XMlFile1.xml … ) For the sake of this demo I created 3 activities for WriteLine as shown below :

<?xml version="1.0" encoding="utf-16"?>
<SequentialWorkflowActivity
    x:Name="SequentialWorkflowActivity"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"

    xmlns:at="clr-namespace:WorkflowProject1;Assembly=WorkflowProject1,Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">

        <at:WriteLine
            x:Name="a1"
            Text="Line 1"
            TextColor="Cyan">
        </at:WriteLine>

        <at:WriteLine
            x:Name="a2"
            Text="Line 2"
            TextColor="Yellow">
        </at:WriteLine>

        <at:WriteLine
            x:Name="a3"
            Text="Line 3"
            TextColor="Green">
        </at:WriteLine>

</SequentialWorkflowActivity>

Now if did notice in the XML above we are using a namespace called “xmlns:at”  @ Line 7. What is ‘at’ ? … I just made that up AT are my initials 😉 But here is the important ( and sneaky ) step …

Do not forget to add project reference(s) to your assemblies which you want to use for activities in the XML

That said I need to add a reference to “WorkflowProject1” assembly to “WorkflowConsoleApplication3” project. And finally …. now is the time to make some changes to your Program.cs file as below : Notice that using WorkflowRuntime instance’s CreateWorkflow function we can feed the XML ( Line 22 ) that we just created and then Start() on Line 24 … would actually execute the workflow.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Xml;
using System.Threading;

namespace WorkflowConsoleApplication3
{
  class Program
  {
    static void Main(string[] args)
    {
      using (WorkflowRuntime runtime = new WorkflowRuntime())
      {
        AutoResetEvent waitHandle = new AutoResetEvent(true);
        XmlReader workflowReader = XmlReader.Create("..\\..\\XMLFile1.xml");
        try
        {
          WorkflowInstance workflowInstance = runtime.CreateWorkflow(workflowReader);

          workflowInstance.Start();
          waitHandle.WaitOne();
        }
        catch (Exception ex)
        {
          throw;
        }
        Console.ReadKey();
      }
    }
  }
}

If I’d try to execute I might get a console window as shown below : There you have it ! … A very basic console application which can load and execute workflows on the fly !

Advertisements

Published by

Aarsh Talati

Software Developer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s