Introduction
This article involves a design pattern that helps to write the code in a way that makes it very easy to change the work flow. Usually, there are different approaches to update the flow dynamically like using database but this article explains the use of Unity Framework and config file. Changing the flow and deploying to production usually involves code change and retesting everything as we deploy either a whole package or just one DLL. But having the flow in the config file and using Unity Framework to implement it gives you the flexibility in your flow without the need of any code change.
Background
Before this article, it would be more beneficial that you refer to Microsoft Unity and How to use Unity in ASP.NET MVC Framework articles to get a better understanding about how Unity works and how can it solve most of our problems making life easier. Also, go over Unity Configuration schema link to know different Unity tags and schema details.
Business Requirement
I had a business requirement where the expectation was to keep the workflow implementation as loosely coupled as possible that there should be minimum/no code change required when we wish to change the workflow. Intention of this approach is to have the setup in such a way that a small change in the config file should reflect the new workflow without needing to make any code change. As deploying a config file is very simple, it gives the opportunity to switch the flow and also rollback to original workflow quickly if something goes wrong.
Using the Code
Before starting with coding, we need to get Unity Framework Package from Nuget Package manager. To grab the package, go to Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution.
For the demo, I'm using a simple Console application project type. I have four tasks/steps which implement a single interface ITask
.
We've registered all these objects using Unity in the config file.
Note: I've written the objects and registered it in such a way that we can use the same create new workflows or update. So at some point, I wish to create a new workflow, all I need to do is create a new Registration in Unity Config with corresponding steps and we're ready to roll.
Now is the time to see this code in action.
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
Console.WriteLine("Executing basic workflow...");
IWorkFlowManager workFlowManager = container.Resolve<IWorkFlowManager>("BasicWorkflow");
workFlowManager.Execute();
Console.WriteLine("Executing Advanced workflow...");
workFlowManager = container.Resolve<IWorkFlowManager>("AdvancedWorkflow");
workFlowManager.Execute();
Here, when I resolved my IWorkFlowManager
workflow with that is registered by the name "BasicWorkflow
" returns the object with the tasks in sequence and then executes it. Here in the example, we have four tasks in the workflow "BasicWorkFlow
" and when we execute it, all the four tasks gets executed.
If in future, I plan on changing my workflow steps/tasks and no longer need to use TaskB
, all I've to do is update the config file and remove it from "BasicWorkFlow
" Register
tag and boom, your flow is updated. It is as simple as that.
I've another "AdvanceWorkflow
" that uses the same steps but different registrations in Unity config. We change the property values and it's a whole new object with the same business logic (can be changed based on our requirement).
Points of Interest
The best part of this exercise is that I realized how extensively Unity can be used when we switch to config file implementation. This design pattern can be integrated with any Creational, Structural or Behavioral design patterns. Although it adds a little complexity to the code, once it is mastered, it can help to make the code modular and less coupled. If implemented correctly, you can have your feature toggling just like plug and play.