Welcome to Dejan's Blog

xworkflows

Introduction
Installation
Basic concepts
Getting Started
Entities
Actions
Events
Workflow
Error handling
Advanced usage
Examples

Getting Started

This section will guide you through the process of setting up XWorkflows and implementing a basic workflow for an entity in your .NET project. By the end of this guide, you will have a clear understanding of how to use XWorkflows to manage workflows on your entities efficiently.

Step 1: Installation

First, make sure you have the XWorkflows library installed in your .NET project. If you haven't installed it yet, follow the instructions in the Installation section to add the package using NuGet or .NET CLI.

Step 2: Define Your Entity

To get started with XWorkflows, you'll need an entity that will be subject to workflow state transitions. For demonstration purposes, let's create a simple OrderEntity class representing an order in an e-commerce application:

public class OrderEntity : IWorkflowStateEntity<State>
{
    public string Identifier { get; set; }
    public State State { get; set; }

    public async Task<string> GetIdentifier()
    {
        return Identifier;
    }

    public async Task<State> GetState()
    {
        return State;
    }

    public IEnumerable<Type> AllowedTransitions()
    {
        return new List<Type>();
    }
}

In this example, OrderEntity implements the IWorkflowStateEntity interface, which defines methods to get and set the entity's state and identifier.

Step 3: Create Custom States

Now, let's create custom state classes that define the states the OrderEntity can transition through in its workflow. For simplicity, we'll define three states: Created, Submitted, and Canceled.

public class CreatedState : MyWorkflowState
{
    public override string Identifier => "Created";

    public override IEnumerable<Type> AllowedTransitions()
    {
        yield return typeof(SubmittedState);
        yield return typeof(CanceledState);
    }

    public async override Task<State> GetState(OrderEntity data)
    {
        return State.Created;
    }
}

public class SubmittedState : MyWorkflowState
{
    public override string Identifier => "Submitted";

    public override IEnumerable<Type> AllowedTransitions()
    {
        yield return typeof(DeliveredState);
        yield return typeof(CanceledState);
    }

    public async override Task<State> GetState(OrderEntity data)
    {
        return State.Submitted;
    }
}

public class CanceledState : MyWorkflowState
{
    public override string Identifier => "Canceled";

    public override IEnumerable<Type> AllowedTransitions()
    {
        // No transitions allowed from CanceledState
        yield break;
    }

    public async override Task<State> GetState(OrderEntity data)
    {
        return State.Canceled;
    }
}

Here, each state class extends MyWorkflowState and overrides the Identifier property and AllowedTransitions method to define its unique behavior.

Step 4: Implement Actions and Events

Next, let's create actions for our workflow. Actions represent specific operations that trigger state transitions. For this example, we'll create SubmitOrderAction, CancelOrderAction, and DeliverOrderAction.

// Implement SubmitOrderAction, CancelOrderAction, and DeliverOrderAction classes
// ...

// Define events for each action (optional)
// ...
For brevity, we'll omit the implementation of actions and events in this example.

Step 5: Define Your Workflow

With custom states, actions, and events in place, we can now define our workflow for the OrderEntity.

public class OrderWorkflow : WorkflowBase<OrderWorkflow, OrderEntity, State>
{
    public OrderWorkflow(IEnumerable<IWorkflowOwner<OrderWorkflow>> actions) : base(actions)
    {
    }
}

In this example, OrderWorkflow extends WorkflowBase and is initialized with a collection of actions relevant to the OrderEntity.

Step 6: Execute Actions

Now that we've set up the workflow, let's execute some actions on our OrderEntity. For instance, we can submit an order and deliver it:

// Execute SubmitOrderAction
// ...

// Execute DeliverOrderAction
// ...

Step 7: Error Handling

XWorkflows takes care of error handling when an action is executed without permission to transition the entity to a desired state. It will throw an exception with a meaningful error message, guiding you to resolve the issue.

Step 8: Advanced Usage (Optional)

Once you're comfortable with the basic setup, you can explore more advanced features of XWorkflows, such as customizing the library's behavior, managing multiple workflows, or integrating events to perform post-action tasks.

About me
Me
I'm Dejan Đenić, a seasoned software developer with over 20 years of experience, specializing in .NET backend development, NoSQL databases, microservices, CI/CD, and containerization. I have management experience, emphasizing secure API development. Through my blog and LinkedIn, I share insights, fostering a community of developers, and promoting effective team leadership in software development.
Social Plugin