Passion * Technology * Ruthless Competence

Monday, January 29, 2007

Compiling Workflows

Scott Allen pointed out that if you need to declare top level properties in a XAML only workflow, you can subclass the root activity class, add the properties you want, then specify the custom subclass in the XAML workflow. That doesn't really solve my problem. I'm trying to limit to activity vocabulary that the workflow author has access to. If they can specify their own custom type as the root activity of their workflow, they can also add whatever execution logic they want, which is what I'm trying to avoid.

There is an example in the Advanced Authoring chapter of Essential WF where they describe building a root activity class that generate top level properties as part of the workflow compilation process. The root activity (in the example, it's called "SequenceWithVars") where you can specify the top level parameters in the XAML. Here's an example from the book:

<SequenceWithVars x:Class="Workflow1xmlns="...xmlns:x="...">
  <SequenceWithVars.VariableDecls>
    <VariableDecl Name="OrderProcConversationType="{x:Type System.Guid}"/>
  </SequenceWithVars.VariableDecls> 

<!-- Remaining workflow XAML goes here --> 

</SequenceWithVars> 

The SequenceWithVars type includes a custom ActivityCodeGenerator that loops thru the VariableDecls collection and adds a top-level property (via CodeDOM) for each VariableDecl instance. You end up with a workflow class that looks like this:

public partial class Workflow1 : SequenceWithVars
{
  public static DependencyProperty OrderProcConversationProp =
    DependencyProperty.Register("OrderProcConversation",
          typeof(Guid), typeof(Workflow1));

  public Guid OrderProcConversation
  {
    get { return (Guid)base.GetValue(Workflow1.OrderProcConversationProp); }
    set { base.SetValue(Workflow1.OrderProcConversationProp, value); }
  }

  //Remaining WF type declaration goes here
}

In order to use the XAML workflow with the SequenceWithVars activity, you do need to compile the XAML first using the WorkflowCompiler class. WorkflowCompiler.Compile() returns a compiled type which can then be passed to CreateWorkflow. But adding the separate compile step is a small price to pay, in my opinion. This approach lets me limit the workflows to XAML only while still allowing for top level properties which are needed in many data binding scenarios.

Update: removed syntax highlighting because it looked bad in my news reader.

Later Update: Fixed syntax highlighting.

Posted By Harry Pierson at 3:51 PM Pacific Standard Time
Friday, February 02, 2007 11:12:52 AM (Pacific Standard Time, UTC-08:00)
if(this comment has anything interesting)
{
you should read it
}
else
{
it is just a waste of time
}
Comments are closed.

SoCal Code Camp

PDC08

patterns & practices
Summit 2008

Change Congress
Recent Bookmarks
Tags .NET Framework (2) ADO.NET (5) Agile (7) AJAX (3) Architecture (284) Guidance (6) Interop (2) Modelling (61) Patterns (7) Process (4) SOA (93) Web Services (5) ASP.NET (24) Battlestar Galactica (3) BI (2) BizTalk (4) Blogging (115) dasBlog (11) Podcasting (4) BPM (1) C# (10) C++ (4) Capitals (5) CardSpace (3) CLR (2) College Football (10) Comedy Central (1) Community (81) Concurrency (6) Consumer Electronics (1) Database (13) Dependency Injection (2) Development (117) C Plus Plus (1) Embedded (5) Lanugages (37) Media (2) P2P (11) Rotor (1) SharePoint (6) SOP (3) DIY (1) DLR (16) Domain Specific Languages (13) Durable Messaging (5) Dynamic Languages (10) Dynamic Silverlight (1) Education (3) Enterprise 2.0 (1) Entertainment (14) ETech (15) F# (51) Functional Programming (17) Game Development (2) Guidance Automation (3) Hardware (8) HawkEye (3) Hockey (29) Home Electronics (1) Home Network (5) Humor (5) IASA (1) Idempotence (3) infrastructure (5) Instrumentation (4) Integration (2) IronPython (45) IronRuby (12) Java (2) Job (3) LINQ (23) Live Mesh (2) Lost (1) Master Data Management (1) Media 2.0 (6) Microsoft (30) MIX06 (2) Mobile Phone (1) Monads (5) Morning Coffee (172) Object Oriented (4) Office (5) Open Source (5) Open Space (2) Operations (3) Other (135) Art (1) Books (1) Family (31) Games (18) General Geekery (26) Home Theater (1) Movies (23) Music (20) Politics (3) Society (1) Sports (37) Working at MSFT (15) Parallel Programming (3) Parsing Expression Grammar (16) patterns & practices (2) PDC08 (5) Politics (47) PowerPoint (2) PowerShell (34) Presentation (5) Projects (1) HawkWiki (1) Python (4) Quote of the Day (4) Refactoring (1) Research (2) REST (18) Reuse (5) Robotics (2) Rock Band (4) Rome (5) Ruby (23) Ruby on Rails (1) Sci-Fi (2) Scripting (4) Security (3) Service Broker (14) SharePoint (2) Silverlight (18) Social Software (1) Software + Services (2) Software Design (1) Software Factories (11) Software Industry (1) Spark (1) SQL Server (2) Stephen Colbert (1) TechEd (7) TechEd06 (1) TechRec League (1) Television (6) Travel (6) Unified Client (1) Unit Testing (4) USC (1) UX (1) Virtual PC (2) Visual Basic (1) Visual Studio (20) Volta (2) Washington Capitals (34) WCF (31) Web 2.0 (65) Web Services (5) WF (21) Windows Live (23) WPF (7) Xbox (1) Xbox 360 (53) XML (11) XNA (14) Zune (4)
Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion.