DEV Community

Cover image for Meridian Workflow – Build Type-Safe, Fluent Workflows in .NET +8 Without the Bloat
Mohammad Anzawi
Mohammad Anzawi

Posted on

Meridian Workflow – Build Type-Safe, Fluent Workflows in .NET +8 Without the Bloat

πŸš€ Meridian Workflow – Build Type-Safe, Fluent Workflows in .NET 8 Without the Bloat

Workflows are everywhere β€” approvals, onboarding, document routing β€” but most engines are either overkill or too rigid.

Meridian Workflow is a lightweight, developer-first engine for .NET 8+ that gives you full control using clean, fluent, and type-safe definitions. No external dependencies. No XML. No drag-and-drop GUIs. Just powerful code.


🎯 Why Meridian?

Unlike legacy engines, Meridian is:

  • βœ… Fluent & type-safe β€” define workflows in code with full IDE support
  • 🧩 Pluggable β€” use hooks, custom logic, file providers, and task handlers
  • πŸ” Secure β€” assign actions by user, role, or group
  • 🧱 Clean β€” built Clean Architecture in mind
  • ⚑ Zero-dependency β€” works in microservices or monoliths

Whether you're automating approvals or managing complex state transitions, Meridian gives you full control with minimal effort.


πŸš€ Quick Started in 5 Steps

1. Define Workflow Data Model

public class LeaveRequestData : IWorkflowData
{
    public string Reason { get; set; } = string.Empty;
    public int Days { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

2. Define the Workflow

public class LeaveRequestWorkflow : IWorkflowBootstrapper
{
    public void Register(IWorkflowDefinitionBuilder builder)
    {
        builder.Define<LeaveRequestData>("LeaveRequest", definition =>
        {
            definition.State("Pending", state =>
            {
                state.Action("Approve", "Approved");
                state.Action("Reject", "Rejected");
            });

            definition.State("Approved", state => state.IsCompleted());
            definition.State("Rejected", state => state.IsRejected());
        });
    }
  }
Enter fullscreen mode Exit fullscreen mode

3. Register Meridian Workflow Engine

builder.Services.AddMeridianWorkflow(options =>
{
    options.Workflows =
    [
        new LeaveRequestWorkflow(),
    ];
});
Enter fullscreen mode Exit fullscreen mode

4. Use the Engine

public class MyClass
{
    public MyClass(IWorkflowService<LeaveRequestData> leaveRequestWorkflow) 
    {
        // use the leaveRequestWorkflow to create, execute action, get history, get request, get logged-in user tasks, ...etc
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Visualize the Workflow (Optional)

workflowDefinition.PrintToConsole();
Enter fullscreen mode Exit fullscreen mode

πŸ”Œ Plug Into Real-World Needs

Meridian comes with built-in support for:

Feature Plug In With...
File Upload IWorkflowFileStorageProvider<TReference>
Custom Business Logic IWorkflowHook<TData>
Task Lifecycle Auto-task generation per action
Action Authorization Role/User/Group filters on each action
Auto Execution Conditional auto-actions in workflow DSL

🧠 Hooks: Add Business Logic Cleanly

  • Purpose: Execute logic during request lifecycle (create, transition, entry/exit).
  • Types:
    • Workflow Definition
    • OnCreateHooks (When a new request is created)
    • OnTransitionHooks (When request transitions)
    • State
    • OnEnterHooks (when request enters the state)
    • OnExitHooks (when request exits the state)
    • Action
    • OnExecuteHooks (when user takes an action)
public class NotifyManager : IWorkflowHook<LeaveRequestData>
{
    public Task ExecuteAsync(WorkflowContext<LeaveRequestData> context)
    {
        Console.WriteLine("Notify: New request created.");
        return Task.CompletedTask;
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ“Ž Attach Files Without Complexity

public class LeaveRequestData : IWorkflowData
{
    public WorkflowFile<WorkflowFileAttachment> MedicalReport { get; set; } = new();
}
Enter fullscreen mode Exit fullscreen mode

Implement your file storage like:

public interface IWorkflowFileStorageProvider<TReference>
{
    Task<TReference> UploadAsync(WorkflowFileAttachment attachment);
}
Enter fullscreen mode Exit fullscreen mode

πŸ›  Use Cases

  • πŸ“… Leave requests with multi-step approvals
  • 🧾 Document reviews with file uploads
  • πŸ›  Support tickets with escalation and SLA
  • πŸ§‘β€πŸ’Ό HR onboarding with task delegation
  • 🧠 Any domain requiring state + logic + history > AND MORE...!

🌟 Ready to Try It?

πŸ“– See full documentation and deep-dive examples in the GitHub README

πŸ“¦ NuGet: Coming soon β€” follow the repo to get notified

⭐ Star the project to support its growth!

πŸ‘ Contributing

Want to help?

  • Submit hooks, templates, and advanced samples
  • Improve test coverage
  • Build roadmap features like timeout, delegation, or JSON DSL
  • Report bugs or usability improvements

πŸ§ͺ Unit tests are still in progress β€” help is appreciated!

πŸ“„ License

Apache License 2.0 β€” free for use in open-source and commercial apps.

Top comments (0)