Monthly Archives: August 2006

Finally some bits!

I’ve been teasing for a while about my Atlas-base Windows Workflow designer for a while.  Its just that although I had some basic functionality working months ago – it has taken me this long with all the other consulting and training I’ve been doing to actually get things working to what I consider a beta level.

So with this post I am announcing beta 1 of the Atlas Workflow Designer.  I am putting up source code – but I am releasing it under the MIT license (which basically means you can use it for any purpose – even commercial – you just have to leave my copyright notice in it so I get credit :)).

Any bug reports are welcome – although code reviews are not ;-).  Personally I am happy with the functionality – I am not necessarily happy with the way all the code is factored.  Some of it to be perfectly honest is a total hack.  Mostly in the Atlas based “class” that runs the designer in the browser.  There is some serious refactoring that needs to get done there, which I will be working on for future releases.  Also – the persistence layer (saving the xaml and rules to the database) isn’t as layered as I’d like (I have plans for a workflow persistence provider so different stores can be easily plugged in).  Also the coupling between the javascript and the service is a little tight – but that may be unavoidable in this particular application.

The biggest thing to get working better is the property grid and rules.  As of now – all you can put in for rules is “true” (yes – I know this sucks – but making a near full-featured rule editor in the browser is another big task).   There also may be some other property types that cause trouble –  but I think that is mostly taken care of.  

You can put bug reports here or email them to me – but remember – I am giving this code away essentially – I am not charging you for it ;-).  But – if you are someone in need of consulting with WF (whether with designers or any other issues) please drop me a line :)

I’ll try to post a camtasia of myself using it later so you can get a handle on how it works – plus there is a slightly weird issue in Mozilla (where you can drop the activities is pretty funky right now – but pretty much everything else works).  You’ll need SQLExpress installed to get the persistence layer to work correctly (or import the mdf into SQLServer and change the connection string in the web.config). 

Anyway – enjoy – hopefully this will be useful.

AtlasWorkflowDesigner.zip (947.94 KB)

Tech Eds

Paul is having fun at TechEd Australia talking about WF – I am looking forward to doing the same at TechEd Hong Kong at the end of September (also just looking forward to going to Hong Kong!).

I hope that the image on this page is the speaker “outfit” :)

I’ll also be doing two talks on Atlas – should be a blast.

Lest you all think me a MS Shill

Here’s something I hate about WF.  I am doing work on my Atlas based HTML designer tonight and I re-ran into something I’ve run into before – the design of WorkflowDesignerLoader (the class that loads Activities into the Workflow Designer).  WorkflowDesignerLoader sucks because it assumes the use of a file.  Especially the RuleConditionDialog and RuleSetDialog’s usage of it (they both ask for the file name and then ask for a TextReader or TextWriter with a .rules path) because it wouldn’t have been that hard to have it not be so tied to the idea of a file path and still be usable by VS.NET as well as applications that want to use the designer but store the Workflow and Rules somewhere else.

You have to understand a technology to use it effectively…

This of course is something I believe pretty intensely having been a trainer for the last 10 years or so.  Scott and Brian (and Tomas has sort of piled on) have posted a couple of entries on how they thing Windows Workflow Foundation (WF) might be too complex.  In general I think they are pretty much totally wrong (isn’t disagreement and discourse the cool think about the web? ;-) ).  First I will address their particular points directly – and then give my overall assessment of WF.  And, in full-disclosure, although sometimes people mistake me for an MS employee – I am *not* .

First Brian’s points (not to pick on him – but since he was first to post I’ll respond to his main points first):

1) On properties.  So here Brian has an interesting point that events are displayed in the properties grid in a way that are not segregated from “properties” in the way other .NET objects properties are. But the thing he misses is that *most* events are (and should be) DependencyProperties.  Because they are DependencyProperties they can be bound using ActivityBind, and from that POV they do really belong in the same part of the property grid (since you should be binding an Event of one Activity to another Activity – you aren’t using the *normal* += syntax when binding those two objects together).  This point is pretty minor IMO and so is my response.  When writing WF properties and events there really isn’t much difference in the syntax.

2) Code Conditions.  So why do CodeConditions have an EventArgs?  VB.NET. VB.NET cannot deal with delegates who have a return value (unless this has been fixed and I didn’t know about it).  Now in generally he misses the point here as well.  In *most* real WF applications – you don’t want to be using CodeCondition, you want to be using DeclarativeRuleCondition since you’ll want the flexibility of the WF rule execution rather than hardcoding conditions in code.  Also – since the *preferred* model of WF is to have as litle code as possible in your Root workflow (which enables more dynamic scenarios as well as XAML creation of workflows) – using CodeCondition is really just for demos and such IMO.

3) HandleExternalEvent/CallExternalMethod.  Granted, communication between the Host and running workflows isn’t perhaps the best part of WF.  But the barrier is there for a good reason – because the model of WF supports persisting workflow instances.  If a reference to an object could be passed directly into a workflow instance, that could cause issues when using persistence.  Now – Is using HEE/CEM complex?  Perhaps at first, but once you get used to it – it really isn’t all that complex – *and* generally on a particular WF project you’ll have your interface and types defined pretty early in the process and then like magic – you are done and can get on to writing other Activities. 

Also – how much more complex is that than defining a WCF (Indigo) ServiceContract interface and corresponding message types, and the configuration entries for the bindings, etc. etc. etc.?  I think it is just about as complex – which really tells me it is about as complex as it needs to be to be generic.

Now – you also have to remember that HEE/CEM is just *one* way to communicate between the host and the workflow instances.  The real communication mechanism (that HEE and the ExternalDataExchangeService use) is the WF Workflow Queuing mechanism.  So if HEE/CEM is too complex or not complex enough (which is actually what I’ve run into a number of times) then you can create Activities that listen for application specific queues and create services that Activities can ask for to communication to the Host.  The big thing to remember is that this indirect communication is essential for the WF model to succeed.

Also – he fails to mention the ability (in a very simple workflow) to pass parameters into a Workflow Instance and get parameters back out.  That is probably the mechanism you’d use in a “WF-lite” kind of WF usage.

Now on to Scott:

Scott doesn’t have complaints really (ok a few about the WF designer – I’m leaving those alone for brevity) – but he really has a list of “gotchas”.  Now – I would argue in return that every runtime (Java, .NET, ASP.NET, WCF, .NET Remoting, BizTalk) all have “gotchas” – which generally related to understanding the model of that particular runtime or library.  That being said – here are my responses to his points:

1) Spawned execution contexts.  These are really super important in terms of the model.  What part of the model?   Compensation for one.  If each child inside of a While Activity didn’t have a persistable context – then it would be impossible to come back to that activity at some time in the future (could be years – that is what the model is meant to support) and tell that activity to compensate, since that activity would have no state to remember what to compensate.  Also in persistence it is vital to remember all the activities that have executed.  So – yes in general you need to be really careful that your Activities are all Serializable.  This is true in other runtimes as well (like when you store objects in out-of-proc Session in ASP.NET or work in .NET remoting – so it really isn’t anything new for most .NET developers).

2) See #1

3) So this is something I’ve argued about on the WF forums – how is this different than any random .NET code that uses System.Transactions?  It isn’t.  If you use more than one connection to SQL Server 2005 you get a DTC transaction.  End of story – happens in C#, VB.NET, ASP.NET, WCF and WF.  So the issue here is that if you using the *Out-of-Box* Tracking and Persistence service – *and* connecting to a database you get DTC transactions.  Just like if you used three objects in a .NET library and all of them used different connection objects.  The OOB Tracking and Persistence and supposed to be references to get your WF application started – and if your application works with them – super , use the OOB implementations.  How to get rid of the DTC?  Build your own Tracking and Persistence service that uses a common connection (like they do if you configure it) with your own code and you now get Local SQL Server transactions – magic if you understand the model.

So what’s the real upshot here?  Are Scott and Brian right or am I right?  I think I’m right of course ;-) And here’s why – I think I understand the WF Model.   Coming from BizTalk has made me understand the power of this model (since BizTalk orchestrations have the ability to do many of the same things WF workflows can do).  Design-time and runtime visibility, the ability to model many different kinds of short and long-running processes (I can go on and on about the features) – are IMO really powerful ways to model real world processes.

You have to remember the charter of the WF Team – they aren’t just building a visual way to write random .NET code – they are creating a way to write applications that are workflow enabled, that need all or some of the potential services that the WF model provides.  The workflow runtime is based on a certain set of assumptions about how applications should be put together (although almost all of those assumptions are pluggable pieces of the infrastructure that you can change if you like).

Perhaps your application won’t do well with the model that WF provides.  But I think with more and more people writing services – there is going to be a big need to tie those services together (not to mention all the applications that people write today which really are workflows whether people realize it or not).  And I think WF is going to be proven to be the best way to write those kinds of applications. 

Is WF easy?  No – I do not think WF is easy.  If it was easy it would hardly be powerful enough to be very useful.

Flame away :-)

The Summer of travel

So I haven’t been posting lately – having spent most of July and August traveling for various events, San Francisco, San Diego, Remond, and now a few days of vacation in Toronto.

Lovely city – makes it hard to work on things.  I will be releasing my ATLAS based WF designer rsn.  Really.  :)