FluentSeq 1.2.0-pre01

This is a prerelease version of FluentSeq.
dotnet add package FluentSeq --version 1.2.0-pre01
                    
NuGet\Install-Package FluentSeq -Version 1.2.0-pre01
                    
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="FluentSeq" Version="1.2.0-pre01" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FluentSeq" Version="1.2.0-pre01" />
                    
Directory.Packages.props
<PackageReference Include="FluentSeq" />
                    
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 FluentSeq --version 1.2.0-pre01
                    
#r "nuget: FluentSeq, 1.2.0-pre01"
                    
#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 FluentSeq@1.2.0-pre01
                    
#: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=FluentSeq&version=1.2.0-pre01&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=FluentSeq&version=1.2.0-pre01&prerelease
                    
Install as a Cake Tool

FluentSeq

FluentSeq provides a fluent interface for creating easy-to-read sequences, eliminating the need for lengthy if/else statements.
The library is written in C# 13 and multi-targets

  • .NET 6.0 - .NET 9.0
  • .NET Standard 2.0/2.1

The library allows you to configure:

  • Sequences with States
  • different kinds of State-Triggers
  • Actions that can be executed on State-Entry, State-Exit or WhileInState
  • Validate a sequence on build to avoid misconfigurations (missing states, triggers, etc.)

The Test coverage for .NET 6.0 - 9.0 is greater than 95%

FluentSeq is the successor of IegTools.Sequencer.

Build Status

  workflow tests

Table of Contents

Installation
Usage
States
Trigger
Actions
Validation
Version Changes
Breaking Changes
Preview next Version v2.0

Installation

The library is available as a NuGet package.

Usage

Configure, build and run a sequence

Create a sequence in a compact style

A simple example configuration and usage for an OnTimer-sequence as xUnit-Test:

using FluentSeq.Builder;
using FluentSeq.Core;

public class OnTimerCreateExampleTests
{
    private ISequence<TimerState>? _sequence;
    private bool _onTimerInput;


    private ISequenceBuilder<TimerState> GetOnTimerConfiguration(int dwellTimeInMs) =>
        new FluentSeq<TimerState>().Create(TimerState.Off)
            .ConfigureState(TimerState.Off)
                .TriggeredBy(() => !_onTimerInput)
            .ConfigureState(TimerState.Pending)
                .TriggeredBy(() => _onTimerInput)
                    .WhenInState(TimerState.Off)
            .ConfigureState(TimerState.On)
                .TriggeredBy(() => _onTimerInput)
                    .WhenInState(TimerState.Pending, () => TimeSpan.FromMilliseconds(dwellTimeInMs))
            .Builder();

    [Theory]
    [InlineData(false, 9, 0, TimerState.Off, TimerState.Off)]
    [InlineData(false, 9, 0, TimerState.Pending, TimerState.Off)]
    [InlineData(false, 9, 0, TimerState.On, TimerState.Off)]

    [InlineData(false, 1, 2, TimerState.Off, TimerState.Off)]
    [InlineData(false, 1, 2, TimerState.Pending, TimerState.Off)]
    [InlineData(false, 1, 2, TimerState.On, TimerState.Off)]

    [InlineData(true, 9, 0, TimerState.Off, TimerState.Pending)]
    [InlineData(true, 9, 0, TimerState.Pending, TimerState.Pending)]
    [InlineData(true, 9, 0, TimerState.On, TimerState.On)]

    [InlineData(true, 1, 2, TimerState.Off, TimerState.Pending)]
    [InlineData(true, 1, 2, TimerState.Pending, TimerState.On)]
    [InlineData(true, 1, 2, TimerState.On, TimerState.On)]
    public async Task Example_Usage_OnTimerConfiguration_Run_async(bool timerInput, int dwellTimeInMs, int sleepTimeInMs, TimerState currentState, TimerState expectedState)

    {
        _sequence     = GetOnTimerConfiguration(dwellTimeInMs).Build();
        _onTimerInput = timerInput;

        _sequence.SetState(currentState);

        await Task.Delay(sleepTimeInMs);
        await _sequence.RunAsync();

        var actual = _sequence.CurrentState;
        actual.ShouldBe(expectedState);
    }
}

Top 🠉

Configure a sequence in a detailed style

A simple example configuration and usage for an OffTimer-sequence as xUnit-Test:

using FluentSeq.Builder;
using FluentSeq.Core;

public class OffTimerConfigureExampleTests
{
    private ISequence<TimerState>? _sequence;
    private bool _onTimerInput;


    private ISequenceBuilder<TimerState> GetOffTimerConfiguration(int dwellTimeInMs) =>
        new FluentSeq<TimerState>().Configure(TimerState.Off, builder =>
        {
            builder.ConfigureState(TimerState.On)
                .TriggeredBy(() => _onTimerInput);

            builder.ConfigureState(TimerState.Pending)
                .TriggeredBy(() => !_onTimerInput)
                    .WhenInState(TimerState.On);

            builder.ConfigureState(TimerState.Off)
                .TriggeredBy(() => !_onTimerInput)
                    .WhenInState(TimerState.Pending, () => TimeSpan.FromMilliseconds(dwellTimeInMs));
        }).Builder();


    [Theory]
    [InlineData(true, 9, 0, TimerState.Off, TimerState.On)]
    [InlineData(true, 9, 0, TimerState.Pending, TimerState.On)]
    [InlineData(true, 9, 0, TimerState.On, TimerState.On)]

    [InlineData(true, 1, 2, TimerState.Off, TimerState.On)]
    [InlineData(true, 1, 2, TimerState.Pending, TimerState.On)]
    [InlineData(true, 1, 2, TimerState.On, TimerState.On)]

    [InlineData(false, 9,  0, TimerState.Off, TimerState.Off)]
    [InlineData(false, 9,  0, TimerState.Pending, TimerState.Pending)]
    [InlineData(false, 9,  0, TimerState.On, TimerState.Pending)]

    [InlineData(false, 1, 2, TimerState.Off, TimerState.Off)]
    [InlineData(false, 1, 2, TimerState.Pending, TimerState.Off)]
    [InlineData(false, 1, 2, TimerState.On, TimerState.Pending)]
    public async Task Example_Usage_OffTimerConfiguration_Run_async(bool timerInput, int dwellTimeInMs, int sleepTimeInMs, TimerState currentState, TimerState expectedState)
    {
        _sequence     = GetOffTimerConfiguration(dwellTimeInMs).Build();
        _onTimerInput = timerInput;

        _sequence.SetState(currentState);

        await Task.Delay(sleepTimeInMs);
        await _sequence.RunAsync();

        var actual = _sequence.CurrentState;
        actual.ShouldBe(expectedState);
    }
}

For more examples → IntegrationTestsFluentSeq/Examples

Top 🠉

Configuration in Detail

States

States can be defined as strings, enums, int, objects, and so on.
Internally they will be stored as type SeqState.

        var builder = new FluentSeq<TimerState>().Create(TimerState.Off)
            .ConfigureState(TimerState.Off)
            .Builder()

// or
        var builder = new FluentSeq<string>().Create("Off")
            .ConfigureState("Off")
            .Builder()

Top 🠉

Trigger

TBD

Top 🠉

Actions

TBD

Top 🠉

Sequence Validation

The validation process ensures the sequence configuration is complete and adheres to the defined principles.
By default, validation is enabled but can be disabled either entirely or for specific states.
The sequence is validated during the build process.

To build a sequence:
_sequence = builder.Build();

Validation Principles:

  • A sequence must have at least two configured states.
  • The initial state must be defined and configured (not null or empty).
  • Every state must have a TriggeredBy(...) method.
  • Every TriggeredBy().WhenInState(s)(...) must point to a configured state.

Validation could be disabled:

  • completely turn off validation
        var builder = new FluentSeq<TimerState>().Create(TimerState.Off)
            .DisableValidation()
            .ConfigureState(TimerState.Off)
            .Builder()
  • or with specifying states that shouldn't be validated:
        var builder = new FluentSeq<TimerState>().Create(Enum.Off)
            .DisableValidationForStates(Enum.State1, Enum.State2, ...)
            .ConfigureState(Enum.Off)
            .Builder()

Top 🠉

Version Changes

Version 1.2.0

  • Multi-Targeting to .NET 6.0 - .NET 9.0 and .NET Standard 2.0/2.1
  • working on warnings regarding nullable reference types (for States)

Version 1.1.0

  • public Release of FluentSeq

Top 🠉

Breaking Changes

Top 🠉

Preview next Version v2

Top 🠉

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  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 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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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.2.0-pre01 114 7/15/2025
1.1.0 95 7/13/2025
1.0.3-pre2 109 3/21/2025
1.0.3-pre1 144 3/8/2025
1.0.2-RC1 183 3/5/2025
1.0.0-RC1 188 3/5/2025

Multi-Targeting, .NET 6.0 - 9.0 and .NET Standard 2.0/2.1