Workflow vs. Command Orchestration

Workflow vs. Command Orchestration

Old forum URL: forums.lhotka.net/forums/t/7456.aspx


SonOfPirate posted on Thursday, August 13, 2009

I know there has been a lot of discussion around Workflow Foundation (WF) and CSLA on this forum and I don't want to rehash all of that.  But... I do have to make some design decisions for a current application and could use some insights to help steer me one way or the other.

From my perspective, WF can serve one of two purposes:

  1. A state machine workflow
  2. Orchestration of multi-step, transactional-type operations

I find the latter fits into CSLA, OOP et al much better because WF manages activities that work with or on our business objects.  The workflow activities are no different than any other object we collaborate with in our applications and provide the glue that makes a set of business objects into an application.

Let me use the example of a service method called PrintReport.  A client calls this method, passing in the report name and number of copies to print, to trigger the printing of a pre-defined report on the server.  In order to perform this operation, I must execute the following steps:

  1. Get the report definition by name
    This is done by calling the indexer on my ReportDefinitionCache business object.  If an object with that name exists, it is returned; otherwise, the GetReportDefinition factory method on my ReportDefinition object is called to load the definition from the data store.
  2. Get the report data source by name
    The ReportDefinition object contains a DataSource property which is used to retrieve the SQL statement from the data store. To do this, I call the DataSourceCache object which will either return an instance from memory or call the DataSource.GetDataSource factory method on my business object.
  3. Obtain the data for the report
    I call the GetData() method on the DataSource object to execute the query used to retrieve the data used for the report
  4. Open the report by name
    I use the FileName property on the ReportDefinition object (from step 1) to open the report file.  It is returned as a Report business object.
  5. Populate the report with the data
    I set the Report object's DataSource property to the data retrieved in step 3
  6. Print the report
    I call the Print method on the Report object

Most of these steps are also used when executing other service methods so I immediately recognized the need to encapsulate them in objects that can be shared across operations.  This could take the form of WF activities or simple command objects.

The question is whether WF is really a good fit?  My concern mostly stems from the performance impact of having a workflow engine running versus having command objects that are bound together to orchestrate the workflow.  For instance, I could have a PrintReportCommand object that uses other command objects representing each step in the workflow and simply be done with it.

On the other hand, WF is a very flexible and convenient way to implement such orchestration.  However, I don't see my workflow changing much so, again, is it worth it to implement WF?

Finally, I will be exposing my services via WCF and I know WCF and WF play very well together.  But, one more time, is it worth it?

Please share your thoughts and experiences - I appreciate the guidance.

 

RockfordLhotka replied on Thursday, August 13, 2009

The primary benefits of WF for orchestration are

  1. Enable power users to alter workflows to take load off developers
  2. Implement complex things like compensating transactions (which are still complex, but are arguably easier with WF)
  3. Suspend/resume workflows for long-running operations (but if you change the workflow structure or code while workflows are suspended you could be in for a nasty surprise, which really limits the value of this feature)
  4. Integration with WCF - of course C# integrates with WCF too, so I think this is really a flipped-around benefit, where WF adds value to WCF rather than WCF adding value to WF

I'm a strong believer in only using a technology, any technology, if I clearly need the benefit(s) it provides. This is because every technology you add to your app increases complexity, increases the learning curve for developers and increases fragility (one more thing can break).

So you need to ask yourself if you need any of these benefits. If you do, then decide if the benefit outweighs the costs. If it does, then go for it.

Copyright (c) Marimer LLC