Another Automation library for .net
Luis Hernández Piney
Posted on February 14, 2022
Motivations
Before I explain what this library can be useful for, it's important for me to explain why I started to develop it.
In September 2020, I suffered a stroke. This led me, in addition to leaving half of my body paralyzed, to suffer all kinds of cognitive problems, such as lack of attention, loss of verbal ability, comprehension, vision problems…a good cocktail. After several months of rehabilitation and with the invaluable work of all kinds of therapists, it seemed that I could recover my life, or at least part of it.
Once the most acute phase of the trauma had passed and I had begun to regain some sense of what was really happening to me, one thing was stuck in my head: I wasn't sure if I would be able to go back to doing my job, or if I would even be able to go back to programming. This was something that no therapist could help me with. I worked every day to be able to get my right hand back, to be able to organize tasks again, to keep my focus, etc. But to reprogram something from scratch was something I would have to work on alone.
So I decided to set a challenge for myself, a tailor-made rehabilitation - something that would force me to be able to maintain that concentration without mentally exhausting myself in just half an hour. I needed to be able to create a plan, follow it, and not fall into absolute frustration when something didn't go according to plan. There were so many things! At that time, to be completely honest, those things were extremely difficult for me.
What can we use it for?
Why use a library dedicated to process automation in particular? After having worked for more than 20 years and dedicating so much of this time to make integrations, either with internal or external systems, such as payment gateways, and seeing several strategies from dedicated applications to make these integrations, such as BPM's, ESB's, custom systems, etc., I believe that in one way or another, when that integration was not direct "A" calls "B" but that it had a certain logic "A" calls "B" with the result of "C", or the error control involves transaction rollback, was when the problems began.
The code that was in charge of the orchestration often lost that separation of responsibilities between integration (data mapping, security, etc.) and the orchestration of the same. The code lost readability and became difficult to reuse and test, among other things.
The creation of this library intends to alleviate all these weaknesses. It covers all kinds of scenarios and allows to have the orchestration encapsulated and tested independently. It also allows the creation of flows as if it were a single service and facilitates the reuse of code, as we can create our own libraries with the definition of our flows.
For more details regarding this library, please visit its GitHub page:
[https://github.com/LHPiney/magnett-automation-core]
Examples
Let's see how we can use this library with basic example, using saga pattern:
We will try to make a saga pattern using orchestration version, we will have two services, order service and payment service. The flow will keep the order state according the result of the payment, here will be the definition for this flow
`
public static class SagaPatternDefinition
{
public static IFlowDefinition Definition { get; }
static SagaPatternDefinition()
{
Definition = FlowDefinitionBuilder.Create()
.WithInitialNode(CreateOrder.Create(NodeName.CreateOrder))
.OnExitCode(CreateOrder.ExitCode.Created).GoTo(NodeName.PreAuthorizePayment)
.Build()
.WithNode(PreAuthorizePayment.Create(NodeName.PreAuthorizePayment))
.OnExitCode(PreAuthorizePayment.ExitCode.PreAuthorized).GoTo(NodeName.ConfirmPayment)
.OnExitCode(PreAuthorizePayment.ExitCode.Denied).GoTo(NodeName.CancelPayment)
.Build()
.WithNode(ConfirmPayment.Create(NodeName.ConfirmPayment))
.OnExitCode(ConfirmPayment.ExitCode.Done).GoTo(NodeName.ConfirmOrder)
.OnExitCode(ConfirmPayment.ExitCode.Failed).GoTo(NodeName.CancelPayment)
.Build()
.WithNode(ConfirmOrder.Create(NodeName.ConfirmOrder)).Build()
.WithNode(CancelPayment.Create(NodeName.CancelPayment))
.OnExitCode(CancelPayment.ExitCode.Done).GoTo(NodeName.CancelOrder)
.Build()
.WithNode(CancelOrder.Create(NodeName.CancelOrder)).Build()
.BuildDefinition();
}
}
`
Full example in
Future
In the future, I would like to complete this library by adding several predefined node types in the standard library, such as API calls, conditional nodes, soap services, and more. I would also like to add the integration of flows as nodes inside another flow (subflows).
In addition, I plan to add at the runner level the possibility of working in a distributed environment to be able to perform part of the workflows in parallel, and improve the traceability and the testing capabilities of the flows with specific extensions to test the flows.
We begin soon with several articles about how to build a complete system using this library form scratch.
Any suggestion, feedback, or collaboration to this project will be, of course, welcome.
Postscript
I started the article commenting on the motivations that led me to do it, so I want to close it by thanking the people who, for more than a year, have encouraged me to continue working and improving. But above all, to the person who has suffered with me all this time and who has given me the greatest motivation to do all this work, thank you for being there, thank you for everything, Diana.
Posted on February 14, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.