Building a simple workflow system with ASP.NET Core
- dotnet
Have you ever had the requirement to implement some sort of business processes and ended up implementing them all over the place in your codebase with lots of if and else statements? Yes, then maybe this post might be interesting to you.
- Building a simple workflow system with ASP.NET Core
- Sample workflow system with ASP.NET Core, Angular and microwf explained - Overview
- Sample workflow system with ASP.NET Core, Angular and microwf explained - the refactoring
- Sample workflow system with ASP.NET Core, Angular and microwf explained - new UI
Some background
In my past I had the chance to work on a powerful workflow engine. From the customers point of view a workflow system can bring huge benefits when it comes to execute workflows and the user of the system can basically start a workflow instance, click through it and let itself guide by the system. All he or she needs to do is to fill out the presented forms and hit save which processes the current state of the workflow. The result could be that the next form gets presented or based on the workflow some emails will be sent or maybe a document needs to get printed and sent to a client.
Since then I had always been interested in workflow systems and studied the patterns and had a look at different workflow engine systems like Windows Workflow Foundations or BPMN Workflow Engine.
microwf - A simple finite state machine (FSM) with workflow character
Recently I came across the requirement to have such a workflow engine available for a project of mine. So I went out and looked again for a suitable workflow engine that fitted my needs.
Because my requirements weren’t that big and I wanted to avoid to have a huge installation and configuration ceremony I built a small library microwf
which is available on nuget.
Processing a workflow with microwf
If you think of how to process a workflow you usually have some sort of a workflow definition IWorkflowDefinition
. Within the definition we define all the required transitions that our workflow need to have.
The interface IWorkflowDefinition
.
1 | public interface IWorkflowDefinition |
Each Transition
can control if the transition can be done, see the CanMakeTransition
-hook. If this results to true
then the BeforeTransition
and AfterTransition
-hook will be executed if defined. Within the BeforeTransition
-hook we are still able to abort the entire transition.
1 | public class Transition |
When it comes to the processing part you need an object instance IWorkflow
that represents an instance of the workflow definition and possibly some context.
The interface IWorkflow
.
1 | public interface IWorkflow |
The WorkflowExecution
class accepts an IWorkflowDefinition
and an IWorkflow
instance. Based on this information it is executing the desired trigger action. The result is always an instance of TriggerResult
where you get the information whether the trigger has been executed or aborted.
A sample is always better
Let’s have a look at a workflow definition for a simple “Holiday Approval”.
In code it looks like the following:
1 | public class HolidayApprovalWorkflow : WorkflowDefinitionBase |
Given the code above we could apply for holiday like that:
1 | var holiday = new Holiday(); |
If everything went fine the result would be that the state of the IWorkflow
instance “holiday” would be “Applied”.
Now you could argue that why not just setting the state
-property on the “holiday” instance directly? Why so much ceremony?
My answer to that question would be:
- Instances of Holiday objects will be treated always the same because the
HolidayApprovalWorkflow
definition exactly defines the transition behavior for each transition. - Imagine a bit more complex workflow and you will be thankful having the transition logic exactly in one place and not distributed within your codebase.
- And last but not least imagine the situation where you need to version a workflow!
Summary
This was the first introductory part of microwf
. I have planned to create one or two other posts that describe the usage of this tiny library within a web api project and an angular frontend.
My ultimate goal would be to have at least the following features:
- super simple user administration with permissions
- assignable user and system workflows
If you go to the github repo you will find a sample ASP.NET Core WebApi application where I started my work.