Friday, May 23, 2008

Workflow Foundation Anatomy

One of my confusions that I ran into when I first started working with Microsoft's Windows Workflow Foundation (WF) was how the WF was structured.  A lot of words were being thrown at me such as Workflow Runtime, Workflow Instance, Core Services, Local Services, and Host Application.  The book that I was reading to learn WF did a piss-poor job explaining these.  Hopefully I can explain them in a way that may help you if you've run into the same problem.

Host Application

This one is fairly straight forward.  This is the application (Windows application, web application, web service, Windows service, etc) that creates and launches the workflow instances.  This is the guy that winds up the robot and lets it go.

iStock_000005521539XSmall

Workflow Runtime

This one is a little more tricky to describe, but the name basically does say it all again.  This is the runtime environment that the workflow instances run in.  The instances are created using the Workflow Runtime and the Workflow Runtime is the guy doing all of the work executing the instances.  The Workflow Runtime is the box that the robot operates in.  The Host Application will use the same box for all the robots doing similar tasks.

The Runtime does a good job isolating the Host Application from the Workflow Instances.  If any Workflow Instance bombs, the Runtime reports it to the Host Application through an event.  Anything that happens to an instance gets reported through events.  So if an instance completes, terminates, aborts, etc., it is reported to the Host Application via an event.  So the robots in the box can't hurt you when they explode because the box is pretty strong and contain the blast.

Workflow Instance

Ok, I've already been throwing this one around a bit, but I'm sure that you get this one already.  If I have a Workflow defined that takes in a set of input A and does an action B, when I need to fire off an execution of this workflow, I create an instance and give him to the Workflow Runtime to execute.  This instance of the workflow is the Workflow Instance (complicated isn't it?).  The Workflow Instance is the robot.

Core and Local Services

Ok, this is where my robot analogy begins to get a little more complicated.  It is important to note here that the Core Services and Local Services are actually an Inversion of Control.  Figuring this out helped me understand the Core and Local Services.

Local Services

Local Services are kind of like the code behind a web service.  A Local Service is nothing more than a class that implements an interface that has the 'ExternalDataExchangeAttribute' applied to it.  A Workflow can call a method on a Local Service using the 'CallExternalMethodActivity'.  The Local Services are loaded into the Workflow Runtime when the Runtime is first being initialized.  The WF provides a way to configure a Workflow Runtime via the application configuration file, so these Local Services can be swapped out after the application has been deployed and thus change how the application can function.  To use the robot analogy, Local Services are basically port holes in the box that the robots can put items in and possibly get items back.  Maybe there is one port hole that the robot can put a chunk of gold in and get gold coins back.  Or maybe the robots just deposit the gold in a port hole and don't get anything back.

For a real-life example, take a banking system.  I may have a Local Service that has functions defined for it such as CreateAccount, CloseAccount, DepositMoney, WithDrawMoney and GetBalance.  My Workflow can now use that Local Service via the interface that it implements (remember, the interface must have the 'ExternalDataExchangeAttribute' applied to it).  And after I've compiled and deployed my application to my test environment, I may want to switch out that Local Service with another one for testing (so that it doesn't hit against live data).  All I have to do is change my application configuration file and run the application again.  So instead of using MyCompany.MyApp.BankingSystem, I'm using MyCompany.MyApp.Testing.BankingSystem.

Core Services

Core Services are even more tricky.  Core Services are software components for the Workflow Runtime written into WF.  They provide functionality such as Workflow Persistence and Tracking (among others).  These are add-on functionality components that you can use to enhance your Workflow experience.  The persistence service gives the Workflow Runtime the ability to save it's running state, including the running state of the Workflow Instances, to a SQL Server database in order to suspend and resume the Workflow Runtime and its Workflow Instances.  The tracking service allows you to track a Workflow Instances so you can watch its progress.  In the robot analogy, since the box (the Workflow Runtime) is basically a black box and I can't actually see the robots, I use the Tracking service to watch what they are doing.  I can hook that up to my Host Application and it's basically a monitor on the side of the box that I can watch any given robot and what it is working on.  Or maybe, it's a unit that records all of the robot's activities (the Persistence service) so if I need to power down the box for the night, the robots can pick up tomorrow where they left off.

 

Note: In order to use the Core and Local Services, any input or output in those service or Workflow parameters must use Serializable objects.

Another Note: When using Local Services, objects are serialized, passed to the Local Service and passed back as a serialized object.  This means that the object going in is not going to be the same instance as the one coming back.  So if you have a Local Service that modifies an object, you're going to need to pass that object back.

Submit this story to DotNetKicks

0 comments: