Summary:
My company required a data driven Work Flow that was generic enough to handle all long running and synchronous business processes. Since I built most of this at home ( I never have time to actually develop projects at work ), I feel liberated to blog about my experience.
High level business requirements were:
- Generic
- External to all applications
- Data Driven
- Quick / Easy manipulation of business rules
High level Technical requirements:
- Fast / easy development of workflows
- Abstracted Data Schema / Model
- Distributed work flow using web services (WCF)
- Asynchronous transitions
- Enterprise Scalable
Here is an example work flow I used:
Before going into the details of the Work Flow, let me outline the
Development environment:
- Language: C#
- Application Platforms: Services, Winforms, WPF
- OS: Windows Server 2003, 2008 & XP
- DB: SqlServer 2005
- ORM: LINQ To SQL (DLINQ)
- WebService Technology: WCF [ HTTPBasicBinding & NETTCPBinding -- though can support any WCF binding protocol]
- Visual Studio 2008 SP1 w/ Resharper 4.1
- Source Control: SVN w/ Tortoise SVN
- Build Server: Team City
- Unit Testing: NUnit & RhinoMocks
-
Aside (DLINQ/LINQ To SQL Concern) One of my concerns was that LINQ to SQL (DLINQ) would go away [ be deprecated ] in lieu of ETF (Entity Frame Work). I would have used ETF, but LINQ is so simple and has lazy loading — ETF has an unsavory way of doing this. I’ll move to ETF in the future, but for now DLINQ rocks. So to decrease the risk of DLINQ going away, I used a strategy Bryan Hunter from FireFlyLogic.com introduced me to. Essentially slipping interfaces in front of the LINQ Datacontext and, in my case, exposing my EntitySets as IQueryable<Entity> lists off of a repository pattern. (I’ll try to post this idea as “Unit Of Work”) |
Basic / High Level Architecture:
The workflow is to be used across the enterprise and load would grow in time. So it had to scale up. To support this the participating components of the Workflow had to be able to run in parallel. There are three main components to the workflow:
1) Workflow Servers : Responsible for transitioning from tasks.
2) API’s : Programming interfaces for external clients / applications to interact with.
Our company has a legacy Access/ADP system that is widely used. In order to allow this system to consume / use the workflow, a database/stored procedure API was created along side the WCF/WS API.
3) Resources : These will be discussed later, but are the building blocks of all custom workflows. They are exposed over Web Services.
Brief Definition of a workflow
Workflows definitions can be complicated, but here the most basic unit of work is a Work Item which is the intersection of three things:
- Case: The item / entity being worked on. (ex: A Customer)
- Task: The action to be done (ex: Make a sales call)
- Resource: The thing/entity doing the work (ex: Employee or the IVR (interactive voice recognition) software making the call.)
A work item is the intersection of these three items (ex: The IVR System will make a sales call the customer) or (ex: An employee will make a sales call to the customer).
Task transitions: A Task has outcomes that optionally transition to additional tasks (ex: Call customer, if they do not answer (outcome), make second call in 2 days).
A Workflow Definition is nothing more than tasks joined to each other via outcomes / transitions. (ex: [task] Call the customer, [outcome] if they do not answer, [task] make second call, [outcome] if customer is interested, take order [action], if customer pays [outcome], send order [action].)
Using Workflow occurs when work items are created based on outcomes. Not all potential tasks / work items occur (ex: if the 1st sales call is successful, the 2nd sales call never occurs)
Here is an example workflow that attempts to sell *something* to a customer. A sales person or IVR (resource) calls (task) the customer (case) trying to get an order. Call up to 3 times, if the customer can not be contacted, send them a mailer. If the customer is interested, take the order and upon payment, send the order.

Let’s do some code!
Simplicity was the key to design. All consuming programmers (those building workflows) should have to develop as little as possible. The framework should take care of the complexity. So what does must be built?
Workflows are built of tasks, but resources are the programming behind the task. A resource is constituted of 3 interfaces:
- ICreateWorkItem – (optional) creates the work item given a case.
- IValidateTransitionToWorkflowItem – (optional) validates that the case can be transitioned to this task & create subsequent workitem.
- IDoWorkItem — (required) responsible for doing the task/action.
These interfaces had to be simple, so they are:
[ServiceContract(Namespace="http://workflow/2008/03")]
public interface ICreateWorkItem
{
[OperationContract]
WorkItemData CreateWorkItem(WorkItemData wd);
}
[ServiceContract(Namespace = "http://workflow/2008/03")]
public interface IValidateTransitionToWorkItem
{
[OperationContract]
ValidateResultData Validate(List<CaseData> cases);
}
[ServiceContract(Namespace = "http://workflow/2008/03")]
public interface IDoWorkItem
{
[OperationContract]
WorkItemData Do(WorkItemData wi);
}
What is required to actually define a task? As with many Domain Specific Languages (DSL), I chose XML. Here is an example of a task definition.
<!– ######################### –>
<!– ## 1st Sales Call ####### –>
<!– ######################### –>
<TaskNodeDefinition >
<Statuses>
<Status IsInitial="True" Name="NotCon" Desc="Not Contacted" />
<Status Name="NoAns" Desc="No Answer" >
<Task Name="2ndCall" Validation="False">
<DueDate Type="delay" increment="days">2</DueDate>
</Task>
</Status>
<Status Name="Yes" Desc="Yes, purchase." >
<Task Name="TakeOrder" >
<DueDate Type="now"/>
</Task>
</Status>
</Statuses>
</TaskNodeDefinition>
And that is all it takes. Define each task w/ the appropriate XML and implement necessary interfaces, and a workflow is only a few steps away. The framework deals with persistence, transitions, scaling and reporting.
alan.huffman Workflow and Business Rules Business Rules, C#, TDD, Tesk Driven Development, WCF, Work flow