In .NET 3.0, Microsoft introduced Windows Workflow Foundations (WF); providing a framework for developing and executing workflows in .NET applications. WF consists of workflow designer tools (visual studio & others), predefined activities (tasks), a rules engine, the workflow runtime (workflow engine) and auxiliary services (e.g. transactions, persistence and tracking services).
Types of Workflows
WF provides two types of workflows for different scenarios, Sequential and State Machine.
Sequential workflows are best suited for tasks where this is clear process that can be defined; such as delivering a package to a customer. Sequential workflows have defined path of activities that is followed from top to bottom. Once a sequential workflow has started, the workflow remains in control, moving between itself between the tasks of the workflow.
State machines are best suited for more complex business processes where the process can move randomly between defined states; for example a DVD player, which can be in one of a possible many different states, such as Playing DVD, DVD Menu, Tray Open, No Disc. Unlike sequential workflows, state machine workflows do not have a defined path, rather a set of states and transitions between states. State machines are event driven and rely on external events to transition the workflow between states.
Activities
Workflow activities are the building blocks of workflows. These building blocks are put together in the Workflow designer, to create a workflow model. Each workflow activity is a standalone component which, within the scope of the workflow, can perform an action, control the flow (of the workflow), communicate (external of the workflow), check conditions or handle errors.
Microsoft has provided a collection of activities with Windows Foundation. Some of the basic activities you should familiarise yourself with are; CodeActivity, WhileActivity, IfElseActivity, DelayActivity.
Custom Activities
Although Microsoft has included a large selection of activities within Windows Workflow, the need will arise where you will need to develop your own custom activities. Anything you can do in custom code can be created presented as a custom workflow activity. A benefit of using custom activities is that the Analyst using the custom activity doesn’t need to understand the internal workings of your activity, just that they drag where they need it and wire up the properties.
Your custom activity will inherit from the either of the following base classes SequenceActivity or Activity from the System.Workflow.ComponentModel namespace. Using a Sequence Activity you can use the drag and drop designer of the Workflow designer using CodeActivities to add custom code. The Activity class requires that you implement your custom code by overriding the ActivityExecutionStatus method.
Activity Properties are used to pass parameters into your custom activity. It is recommended that you use a Dependency Property which allows other activities to bind to your properties. Visual Studio 2008 implements a propdp code snippet to allow easy implementation of Dependency Properties.
Workflow Runtime
The workflow runtime is responsible for executing the workflow models. Like the WCF runtime, the Workflow runtime can be run in any type of host application and runs in a separate thread.
The runtime engine is indifferent to the workflows that it is executing, meaning that same workflow engine will execute many different workflows such as CarOrder or MakeCar workflows.
The following piece of code loads the workflow runtime in a console application. The code also creates an instance of a Workflow and waits for the workflow to complete. As the runtime runs in a different thread to the application, this code uses a waitHandle (AutoResetEvent, lines 5, 6 & 11) to stop the console application closing before the completion of (one) workflow instance.
Parameters can be provided to your workflow when creating the workflow instance. First you must create the parameters as Properties within your workflow class. The CreateWorkflow() method can take a Dictionary object containing the parameters you require.
Communicating with the workflow.
You will notice in the runtime code above, on line 8, the new workflow instance (in this case CarOrder) is created by the Runtime. The workflow instance is created and excuted within the Workflow Runtime, to be able to communicate between the host application and the running workflow, you must use the CallExternalMethod and HandleExternalEvent activities within your workflow.
The activities use a Interface with ExternalDataExchange attributed to communicate through. Any method listed on the interface can be called from CallExternalMethod activities with method parameters being provided via using the properties window of the activity (Illustrated to the right). The HandleExternalEvent activitys will respond to events on an interface that have an Event Argument type derived from ExternalDataEventArgs.
An implementation of your communications Interface is required to provide the gateway between your host application and the Windows Workflow instances. To accomplish this, you assign a ExternalDataExchangeService (part of WF), to the WorkflowRuntime, and then assign your communications implementation as a service to the ExternalDataExchangeService.
Persistence
One of the benefits of WF is the ability to handle long running business processes out of the box. WF provides the ability to persist your workflows to a store using the extendable WorkflowPersistenceService class. An SQL server based implementation of the WorkflowPersistenceService, SqlWorkflowPersistenceService is provided by WF.
Another benefit of adding persistence to the runtime is the ability to scale. If your application is dealing with many workflow instances, the runtime must maintain memory for each instance. By using persistence services, the runtime can unload a data store to free up memory