Jon Flanders' Blog

Compiled Activities to XOML

Sunday, April 30, 2006 9:40:07 PM (GMT Daylight Time, UTC+01:00)

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.

 

WF   #    Comments [3]   

Wednesday, May 03, 2006 4:45:41 AM (GMT Daylight Time, UTC+01:00)
Jon,

I'm not quite sure I'm understanding here how it's working. Under beta 2, at least, I've tried running the code and always failing with a NullReferenceException, in particular here:


CompositeActivity ca = a.CreateInstance(t.BaseType.FullName) as CompositeActivity;

This is running the code against a sequential workflow, since it derives from SequentialWorkflowActivity, which is not defined inside the same assembly as the original workflow, this always fails :)

Anyway, assuming we changed that, the copying of activities from one CompositeActivity to another still fails, because the original CompositeActivity's Activity collection cannot be changed and it seems you can't just reassign the activity a new parent just like that :)

Is something different in later builds that changes all this, or am I jut misunderstanding the code/running it against an incorrect target?

(P.S: I don't think Assembly.LoadFrom() returns null on failure, but I might be wrong :))
Wednesday, May 03, 2006 6:07:56 AM (GMT Daylight Time, UTC+01:00)
Works for me on Beta 2.2 Tomas - I'll try it out on some different example though
Wednesday, May 03, 2006 2:17:22 PM (GMT Daylight Time, UTC+01:00)
I just tried a little bit more, and fwiw, it doesn't work either for xoml-based or code based workflows on beta 2 in my case at least :)

Looks like a really cool and useful tool, though, which is why I wanted to get it to work :)
All comments require the approval of the site owner before being displayed.
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview