Swolfkrow 0.3.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Swolfkrow --version 0.3.1
NuGet\Install-Package Swolfkrow -Version 0.3.1
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="Swolfkrow" Version="0.3.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Swolfkrow --version 0.3.1
#r "nuget: Swolfkrow, 0.3.1"
#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.
// Install Swolfkrow as a Cake Addin
#addin nuget:?package=Swolfkrow&version=0.3.1

// Install Swolfkrow as a Cake Tool
#tool nuget:?package=Swolfkrow&version=0.3.1

Swolfkrow

Swolfkrow (pronounced /ˈwɜː(r)kˌfləʊs/) is a Domain Specific Language (DSL) designed to declaratively compose asynchronous workflows through a fluent API.

Asynchronous workflows

Asynchronous workflows are asynchronous computations that yield an stream of events signaling progress, outcomes, and errors.

In practice, asynchronous workflows are objects implementing the IAsyncEnumerable<out T> interface, with a couple of particularities:

  • The generic type T, named TEvent across the Swolfkrow library, represents the base type from which the types of all events potentially yielded by the asynchronous workflow derive.
  • Yielded TEvent objects are meant to describe significant events occured during the workflow's execution.
  • When enumerated, asynchronous workflows can execute arbitrary asynchronous logic in between yielded TEvent objects.

The Workflow<TEvent> class

Swolfkrow represents asynchronous workflows with an explicit Workflow<TEvent> class that implements the IAsyncEnumerable<out T> interface.

The Workflow<TEvent> class exists both as a semantic anchor with a self-descriptive name, and as a convenient container for the fluent API. It is meaningful during the composition of asynchronous workflows, however the resulting workflow objects behave as expected from any object implementing the IAsyncEnumerable<out T> interface, meaning they will execute their logic and yield events only when enumerated.

Overview

The following subsections briefly describe the different types of asynchronous workflow compositions that can be performed through Swolfkrow's fluent API operators.

Initiations

The family of Start method overloads provides a single entry point to the DSL:

record EventBase(string Description);

IAsyncEnumerable<EventBase> Step1() { ... }

IAsyncEnumerable<EventBase> ComposeWorkflow()
    => Workflow
        .Start(Step1);

Continuations

Asynchronous workflows can be composed as sequences of simpler workflows, where one workflow starts when the previous one finishes yielding events:

record EventBase(string Description);

IAsyncEnumerable<EventBase> Step1() { ... }
IAsyncEnumerable<EventBase> Step2() { ... }

IAsyncEnumerable<EventBase> ComposedWorkflow()
    => Workflow
        .Start(Step1)
        .Then(Step2);

Stateful continuations

Workflow continuations can be based on state explicitly folded from the events yielded by the workflow:

record EventBase(string Description);

IAsyncEnumerable<EventBase> Step1() { ... }
IAsyncEnumerable<EventBase> Step2(int someInfo) { ... }

IAsyncEnumerable<EventBase> ComposedWorkflow()
    => Workflow
        .Start(Step1)
        .Then(
            createContinuation: currentState => currentState * 2,
            computeNextState: (currentState, nextEvent) => currentState + 1,
            initialState: 0);

Intercalations

Asynchronous workflows can be intercalated and executed in the middle of other asynchronous workflows, triggered by events of a specific type and/or satisfying a predicate:

record EventBase(string Description);
record SomethingHappened(string Description) : EventBase(Description);

IAsyncEnumerable<EventBase> Step1() { ... }
IAsyncEnumerable<EventBase> Step2(SomethingHappened somethingHappened) { ... }

IAsyncEnumerable<EventBase> ComposedWorkflow()
    => Workflow
        .Start(Step1)
        .When<SomethingHappened>().Then(Step2);

Side effects

Side effects can be deliberately injected into an asynchronous workflow:

record EventBase(string Description);

IAsyncEnumerable<EventBase> Step1() { ... }
IAsyncEnumerable<EventBase> Step2() { ... }

void LogEvent(EventBase someEvent)
    => Console.WriteLine($"Something happened: {EventBase}")

IAsyncEnumerable<EventBase> ComposedWorkflow()
    => Workflow
        .Start(Step1)
        .Then(Step2)
        .Do(LogEvent);

Interruptions

Asynchronous workflows can be interrupted based on a condition computed on each of the yielded events:

public record EventBase(string Description);
public record SomeError(string Description, Exception Exception) : EventBase(Description);

IAsyncEnumerable<EventBase> Step1() { ... }
IAsyncEnumerable<EventBase> Step2(int someInfo) { ... }

bool IsError(EventBase nextEvent) => nextEvent is SomeError;

IAsyncEnumerable<EventBase> ComposedWorkflow()
    => Workflow
        .Start(Step1)
        .Then(Step2, 42)
        .Until(IsError);
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
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
0.4.0 158 9/1/2023
0.3.2 145 7/22/2023
0.3.1 172 7/3/2023
0.3.0 157 7/2/2023
0.2.5 146 6/18/2023
0.2.4 147 6/12/2023
0.2.3 165 6/9/2023
0.2.2 162 6/6/2023
0.2.1 136 6/4/2023
0.2.0 148 5/29/2023
0.1.3 151 5/29/2023
0.1.2 153 5/25/2023
0.1.1 156 5/22/2023
0.1.0 151 5/21/2023

# 0.3.1 (2023-07-04)
- Fixed the return types of some public api methods.
# 0.3.0 (2023-07-02)
- BREAKING CHANGE: rewritten extension methods as members of a newly added `Workflow<TEvent>` class.
- BREAKING CHANGE: rewritten intercalations as two-step compositions.
# 0.2.5 (2023-06-19)
- Added intercalation overloads.
# 0.2.4 (2023-06-13)
- Added interruptions.
# 0.2.3 (2023-06-10)
- Full review of the comment-based documentation.
- Added `IEnumerable` based overloads of start, continuation, and event continuation operators.
# 0.2.2 (2023-06-07)
- Added synchronous continuations.
# 0.2.1 (2023-06-04)
- Start/continue asynchronous workflows from `Task` and `ValueTask`
# 0.2.0 (2023-05-29)
- Simplified stateful continuations.
# 0.1.3 (2023-05-26)
- Added event continuations
# 0.1.2 (2023-05-25)
- Added `Start` and `Then` overloads with additional arguments
# 0.1.1 (2023-05-22)
- Added stateful continuations.
# 0.1.0 (2023-05-21)
- Initial Version.
- Added workflow continuations.