ModernWorkflows 1.0.0

dotnet add package ModernWorkflows --version 1.0.0
                    
NuGet\Install-Package ModernWorkflows -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ModernWorkflows" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ModernWorkflows" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ModernWorkflows" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ModernWorkflows --version 1.0.0
                    
#r "nuget: ModernWorkflows, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ModernWorkflows@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ModernWorkflows&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ModernWorkflows&version=1.0.0
                    
Install as a Cake Tool

ModernWorkflows

Russian NuGet version .NET License

ModernWorkflows is a thin layer on top of WorkflowCore and its YAML/JSON DSL extension. It adds a set of ready-to-use workflows defined as plain C# classes (no YAML files required), a step for calling one workflow from another as a sub-routine, and a request/response bridge for workflows that need to wait for an external event.

It is meant for applications that mix strongly-typed C# workflows with data-driven YAML/JSON workflows and need both to interoperate.

Core concepts used in the project:

  • ShowMessage, WaitInputValue (built-in workflows, plain IWorkflow<TData> classes, registered automatically);
  • StartWorkflowStep (a step that starts another registered workflow — C# or YAML — and maps inputs/outputs by expression);
  • IWorkflowHostEx (extends IWorkflowHost with StartWorkflowAndAwaitAsync, AwaitCompleteWorkflow(s) and LoadDefinitions for YAML/JSON);
  • IWorkflowEventPublisher, WaitEvent (publish/await an external event from inside a workflow);
  • IMessagePresenter, IWaitInputValue (the two interfaces you implement to plug your own UI/console/API into ShowMessage and WaitInputValue).

Installation

Target framework: .NET 8 (works on higher versions as well)
Install via NuGet:
- dotnet add package ModernWorkflows
Install via Package Manager:
- Install-Package ModernWorkflows

Usage examples

Example 1

Registering ModernWorkflows in ServiceCollection
var serviceCollection = new ServiceCollection();
serviceCollection.AddLogging();
serviceCollection.AddModernWorkflows();
Implementing the interfaces used by the built-in workflows
public class ConsolePresenter : IMessagePresenter
{
    public void Show(string message, bool newLineAfter = false)
        => Console.WriteLine(newLineAfter ? message + Environment.NewLine : message);
}

public class ConsoleWaitInputValue : IWaitInputValue
{
    public string WaitStringInput(string titleKey)
    {
        Console.Write(titleKey);
        return Console.ReadLine() ?? "";
    }

    public int WaitIntInput(string titleKey) { /* ... */ }
    public double WaitDoubleInput(string titleKey) { /* ... */ }
    public decimal WaitDecimalInput(string titleKey, int decimalPoint) { /* ... */ }
    public DateTime WaitDateTimeInput(string titleKey, string dateFormat = "dd.MM.yyyy") { /* ... */ }
}
Starting the built-in WaitInputValue workflow and getting the result
var serviceCollection = new ServiceCollection();
serviceCollection.AddLogging();
serviceCollection.AddModernWorkflows();
serviceCollection.AddTransient<IMessagePresenter, ConsolePresenter>();
serviceCollection.AddTransient<IWaitInputValue, ConsoleWaitInputValue>();

var serviceProvider = serviceCollection.BuildServiceProvider();
var host = (IWorkflowHostEx)serviceProvider.GetRequiredService<IWorkflowHost>();
host.Start();

var completed = await host.StartWorkflowAndAwaitAsync("WaitInputValue", new InputValueContext
{
    TitleKey = "Enter your PIN: ",
    InputValueType = InputValue.Int
});

var pin = (int)((InputValueContext)completed.Data).Value!;
Console.WriteLine($"Pin: {pin}");
// Execution result:
// Enter your PIN: (waits for console input, re-asks on invalid values)
// Pin: 1234

Example 2

Defining your own workflow as a plain C# class
public class MyWorkflowData
{
    public string Name { get; set; }
}

public class GreetStep : StepBody
{
    public string Name { get; set; } = null!;

    public override ExecutionResult Run(IStepExecutionContext context)
    {
        Console.WriteLine($"Hello, {Name}!");
        return ExecutionResult.Next();
    }
}

public class MyWorkflow : IWorkflow<MyWorkflowData>
{
    public string Id => "MyWorkflow";
    public int Version => 1;

    public void Build(IWorkflowBuilder<MyWorkflowData> builder)
    {
        builder
            .StartWith<GreetStep>()
                .Input(step => step.Name, data => data.Name)
            .Then<StartWorkflowStep>()
                .Input(step => step.WorkflowId, data => "ShowMessage")
                .Input(step => step.ChildInputs, data => JObject.Parse("{ \"Message\": \"data.Name\" }"));
    }
}
Registering and starting it
var serviceProvider = serviceCollection.BuildServiceProvider();
var host = serviceProvider.GetRequiredService<IWorkflowHost>();

host.RegisterWorkflow<MyWorkflow, MyWorkflowData>();
host.Start();

await host.StartWorkflow("MyWorkflow", new MyWorkflowData { Name = "Alice" });
// Execution result:
// Hello, Alice!
// Alice

StartWorkflowStep here calls the built-in ShowMessage workflow as a sub-routine, the same way it can call a workflow loaded from YAML/JSON — ChildInputs/ChildOutputs accept either a quoted literal ('"some literal"') or a data./step. expression resolved against the calling workflow's data.


Compatibility

  • .NET 8+

License

The project is licensed under the Apache License. See the LICENSE file for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 96 8/29/2026