Monthly Archives: April 2006

Compiled Activities to XOML

So I’ve been pretty dark lately.  Mostly I have been on a consulting engagement with a company helping them to build their next generation product using Windows Workflow Foundation (WF).  This has been a great gig, not only because of all the cool things we are getting done with WF, but also because the people there are really great to work with.  After the product releases I’ll be able to link to their site, etc.  But until then I’ll be posting little nuggets of knowlege I am gaining from applying WF to a real-world problem.

One of the issues we’ve come up with is how to store our root activities.   Since this system will need some flexibility over time we’ve decided to store the root activites as XAML rather than as compiled activities.  Partly because customers will be able to do customizations after deployment of the main system, and XAML is more flexible in that we can more easily create new workflows using the customer designer we’ve built, and mix and match those workflows with rule more dynamically.  This also means the customization can be done without visual studio or another more complex designer that would include compiling the workflows.

The minor issue here is that the developers are the ones that are going to be creating the basic workflow designs in visual studio.  That means some of the workflows would be compiled and some would be XAML which would be a potential maintenance issue.  So I wrote some code that could take the initial compiled activity and turn it into XAML that could just be executed.  Here’s the code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Serialization;
using System.Xml;

namespace compiledtoxaml
{
class Program
{
static void Main(string[] args)
{
string asmName = args[0];
string className = args[1];
string outFile = args[2];
Assembly a = Assembly.LoadFrom(asmName);
if (a != null)
{

Type t = a.GetType(className);
if (t != null)
{
Activity act = a.CreateInstance(className) as Activity;
if (act != null)
{
CompositeActivity ca = a.CreateInstance(t.BaseType.FullName) as CompositeActivity;
CompositeActivity child = act as CompositeActivity;

foreach (Activity cact in child.Activities)
{
ca.Activities.Add(Activator.CreateInstance(cact.GetType());
}
WorkflowMarkupSerializer s = new WorkflowMarkupSerializer();
XmlWriter xw = XmlWriter.Create(outFile);
s.Serialize(xw, ca);
}
else
{
Console.WriteLine(“Type {0} not an activity”,className);
}
}
else
{
Console.WriteLine(“Unable to load type {0}”,className);
}
}
else
Console.WriteLine(“Unable to load assembly {0}”,asmName);

}
}
}

To make the XAML executable version – the code recreates the child activity tree into a new type that isn’t a derived type.  I can’t tell you how much I am in love with the WF stack and how it makes building a workflow enabled app so enjoyable.