Workflower is a library based on .NET Standard, To handle Finite State Machines (FSM) and workflow management.
Install the latest nuget package into your ASP.NET Core application.
dotnet add package DIT.Workflower
You can also download support for Dependency Injection:
dotnet add package DIT.Workflower.DependencyInjection
using DIT.Workflower;
var builder = new WorkflowDefinitionBuilder<TState, TCommand, TContext>()
.From(TState.State_1)
.On(TCommand.GoNext)
.To(TState.State_2)
.From(TState.State_2)
.On(TCommand.GoNext)
.To(TState.State_3)
.AndOn(TCommand.GoBack)
.To(TState.State_1)
var workflow = builder.Build();
var allowedTransitions = workflow.GetAllowedTransitions(from: TState.State_2);
// allowedTransitions will be 2 transitions
// State_2 -> State_3 (GoNext)
// State_2 -> State_1 (GoBack)
In the Program.cs
, register the workflow factory, defining one or more workflow definitions.
public record PhoneCall(bool Active);
services.AddWorkflowDefinition<PhoneState, PhoneCommand, PhoneCall>(id: "constant-id", version: 1)
// Idle -> Ringing (Incoming)
.From(PhoneState.Idle)
.On(PhoneCommand.IncomingCall)
.To(PhoneState.Ringing)
// Ringing -> Connected (Accept & ctx.Active)
.From(PhoneState.Ringing)
.On(PhoneCommand.Accept)
.To(PhoneState.Connected)
.When(ctx => ctx.Active) // An instance of PhoneCall will become the ctx.
// Ringing -> Declined (Decline)
.From(PhoneState.Ringing)
.On(PhoneCommand.Decline)
.To(PhoneState.Declined)
[Route("[controller]")]
public class SampleController : JsonApiControllerBase
{
private readonly IWorkflow<PhoneState, PhoneCommand, PhoneCall> _workflow;
public SampleController(IWorkflowFactory<PhoneState, PhoneCommand, PhoneCall> factory)
{
_workflow = factory.CreateWorkflow(id: "constant-id", version: 1); // Optional version param to support versioning on workflows.
}
[HttpGet("{state}")]
[ProducesResponseType(typeof(JsonApiSingleDataResponse<InitiateRequest>), StatusCodes.Status200OK)]
public ActionResult GetRequest(PhoneState state, bool isActive)
{
var phoneCall = new PhoneCall(isActive)
var transitions = _workflow.GetAllowedTransitions(context: phoneCall, state);
return Ok(transitions)
}
}
Note: If you do not specify an id for the workflow, the default id is:
$"{typeof(TState).Name}_{typeof(TCommand).Name}_{typeof(TContext).Name}";