Jon Flanders' Blog

One reason why to created your own WorkflowLoaderService

Sunday, October 22, 2006 8:08:34 AM (GMT Daylight Time, UTC+01:00)

Harry Pierson was in my WF/WCF course I taught a few weeks ago.  He posted on his blog about features he thought were cool in WF here.

One of the ones that I thought was interesting that he caught during my course was that the WorkflowLoaderService is actually a pluggable service (just like every other service except for the WorkflowQueueingService).   So of course it came to my mind to show an example of why you might want to create a custom loader service.

The WorkflowLoaderService is a very simple API - it has two methods name CreateInstance both which return an instance of Activity.  Everytime a Host calls WorkflowRuntime.CreateWorkflow - the WorkflowLoaderService is called to actually create the instance.  One of the CreateInstance methods is for compiled Activities (the one that takes as its argument a Type) and one for XAML activation (the one that takes as its arguments two XmlReaders - one for the workflow and one for rules).

The DefaultWorkflowLoaderService is fairly simple - the CreateInstance that takes a Type uses Activator.CreateInstance to create an instance of the Activity Type.  The one that takes XAML is slightly more complex - but essentially uses the WorkflowMarkupSerializer to turn the XAML into an Activity.

So why might you want to replace this service?  Well - there are many scenarios - but one that always comes to mind for me resolves around rule loading. 

One of the great features of WF is to be able to model some of you logic in rules versus code.  In Visual Studio - whenever you add rules, those rules are stored in a .rules file along side your workflow files.  These .rules files are then compiled into the assembly as resources.  Whenever an Activity first needs a rule, there is an infrastructure that loads the .rules file into a RuleDefinitions type (containing both any RuleSets and RuleConditions) - and stuff the object into a well-known DependencyProperty in the root Activity.

One of the features of rules that is so useful is being able to replace them at runtime with a different set of rules - but with the DefaultWorkflowLoaderService - the only way you can do that is if you use XAML activation.  But what if you want to replace rules on a compiled Activity type without having to recompile it.  The default infrastructure doesn't allow this.

But - if you build your own WorkflowLoaderService - when a compiled Activity type is requested - you could read the rules from an alternate location (based on configuration or some other algorithm) and then dynamically create the RuleDefinitions and stick it into the Activity using the well-known DependencyProperty.  Here is the code that does this in a simulated way (note that you'd have to change the algorithm that loads the alternate rules to something useful):

public class DynamicRuleWorkflowLoader : DefaultWorkflowLoaderService
{
protected override System.Workflow.ComponentModel.Activity CreateInstance(Type workflowType)
{
Activity a = base.CreateInstance(workflowType);
WorkflowMarkupSerializer s = new WorkflowMarkupSerializer();
object o = s.Deserialize(XmlReader.Create("AlternateRules.xml"));
a.SetValue(RuleDefinitions.RuleDefinitionsProperty, o);
return a;
}
protected override Activity CreateInstance(System.Xml.XmlReader workflowDefinitionReader, System.Xml.XmlReader rulesReader)
{
return base.CreateInstance(workflowDefinitionReader, rulesReader);
}
}

WF   #    Comments [3]   

Friday, November 10, 2006 12:23:07 AM (GMT Standard Time, UTC+00:00)
Hey Jon,

This is actually quite powerful.

As for the rules example - a better approach is to have the rules centrally based and add a rules service to the Runtime which loads/caches and calls the rules upon the request of the individual WF. But that's not the reason for my post.

One of the limiting things in the 'CallWorkflow' shape is that you have to at design time specify the WF you're going to call (I know there's dynamic update etc. but it's a world of pain in statebased wf's with all the copied contexts).

How about - creating your own WF loader then allows you to specify some terms in the Call WF activity that would be interpreted by the custom WF loader into ???
and return back the WF of choice from where ever, depending on rules, logic etc etc

Nice one! Thanks and thanks for your student also.
Friday, November 10, 2006 12:25:08 AM (GMT Standard Time, UTC+00:00)
Sorry - just re-read and saw you mentioned about the alt. rules location.
Wednesday, July 11, 2007 3:42:03 PM (GMT Daylight Time, UTC+01:00)
Jon,

Is there a way I can get in touch with you by email or phone. We have an interesting custom WF project that we would like to discuss with you.

Thanks!

Patrick
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