Excellence.Pipelines.Core 5.0.0

Prefix Reserved
dotnet add package Excellence.Pipelines.Core --version 5.0.0
                    
NuGet\Install-Package Excellence.Pipelines.Core -Version 5.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="Excellence.Pipelines.Core" Version="5.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Excellence.Pipelines.Core" Version="5.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Excellence.Pipelines.Core" />
                    
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 Excellence.Pipelines.Core --version 5.0.0
                    
#r "nuget: Excellence.Pipelines.Core, 5.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 Excellence.Pipelines.Core@5.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=Excellence.Pipelines.Core&version=5.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Excellence.Pipelines.Core&version=5.0.0
                    
Install as a Cake Tool

Pipelines

Table of contents

<br/>

Overview

Pipelines are created using pipeline builders.

IPipelineBuilder<TParam, TResult> is used to create pipelines that accept an argument (TParam) and return a result (TResult).

IAsyncPipelineBuilder<TParam, TResult> is used to create pipelines that accept arguments (TParam, CancellationToken) and return a result (Task<TResult>).

All examples below use IAsyncPipelineBuilder<TParam, TResult>.

<br />

Create pipeline builders

Constructor

A pipeline builder can be created using the public constructor.

Example:

var pipelineBuilder = new AsyncPipelineBuilder<int, int>(serviceProvider);

<br/>

Factory

A new pipeline builder can be created using the factory.

It is possible to pass the IServiceProvider instance as an argument.

Example:

var factory = new AsyncPipelineBuilderFactory(serviceProvider);

var pipelineBuilder = factory.CreateAsyncPipelineBuilder<int, int>();

<br/>

Copy

Copy creates a new pipeline builder from the existing one (source) and returns it.

The configuration (components, target) is copied to a new instance.

A new pipeline builder uses the same IServiceProvider instance as the source one.

Example:

public class TargetService
{
    public Task<int> Compute(int param, CancellationToken cancellationToken) => Task.FromResult(param + 1);
}

/* ... */

var service = new TargetService();

// components and target are copied from the source pipeline builder
var pipelineBuilderCopy = pipelineBuilder.Copy();

var pipelineCopy = pipelineBuilderCopy.BuildPipeline();

<br/>

Add components

A component is a delegate that accepts one parameter (the next step of the pipeline) and returns a delegate containing the current step logic.

Every pipeline executes steps in the order these steps have been added.

<br/>

Use delegate

Use adds the components created from the delegates.

Example:

Func<Func<int, CancellationToken, Task<int>>, Func<int, CancellationToken, Task<int>>> component =
    next => (param, cancellationToken) =>
    {
        var modifiedParam = param + 5;

        return next.Invoke(modifiedParam, cancellationToken);
    };

// one component
pipelineBuilder.Use(component);

// collection of components
pipelineBuilder.Use(new[] { component, component, component });

<br/>

Use interface

A component can be added using the interface implementation.

Example:

public class PipelineStep : IAsyncPipelineStep<int, int>
{
    public async Task<int> Invoke(int param, CancellationToken cancellationToken, Func<int, CancellationToken, Task<int>> next)
    {
        var nextResult = await next.Invoke(param, cancellationToken);

        var result = nextResult * 2;

        return result;
    }
}

/* ... */

// pipeline step is provided by the factory
pipelineBuilder.Use(() => new PipelineStep());

// pipeline step is provided by the factory accepting service provider
pipelineBuilder.Use((sp) => sp.GetRequiredService<PipelineStep>());

// pipeline step is provided by the service provider
pipelineBuilder.Use<PipelineStep>();

<br/>

Add components and execute conditionally

It is possible to add components that are executed only when some condition is met.

<br/>

UseWhen

UseWhen adds the pipeline branch with its configuration that is executed when the condition is met.

When the condition is met the branch is executed and then the main pipeline is executed.

When the condition is NOT met the branch is skipped and the main pipeline is executed.

The pipeline branch is configured using the new pipeline builder instance and configuration delegate.

Example (condition delegate - predicate):

// branch pipeline builder is provided by the factory
pipelineBuilder.UseWhen
(
    (param) => Task.FromResult(param == -1),
    builder => builder.Use(() => new PipelineStep()),
    () => new AsyncPipelineBuilder<int, int>(serviceProvider)
);

// branch pipeline builder is provided by the factory accepting service provider
pipelineBuilder.UseWhen
(
    (param) => Task.FromResult(param == -1),
    builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>()),
    (sp) => sp.GetRequiredService<IAsyncPipelineBuilder<int, int>>()
);

// branch pipeline builder is provided by the service provider
pipelineBuilder.UseWhen
(
    (param) => Task.FromResult(param == -1),
    builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>())
);

<br/>

Example (interface implementation):

public class PipelineConditionTrue : IAsyncPipelineCondition<int>
{
    public Task<bool> Invoke(int param) => Task.FromResult(true);
}

/* ... */

// condition and branch pipeline builder are provided by the factory
pipelineBuilder.UseWhen
(
    () => new PipelineConditionTrue(),
    builder => builder.Use(() => new PipelineStep()),
    () => new AsyncPipelineBuilder<int, int>(serviceProvider)
);

// condition and branch pipeline builder are provided by the factory accepting service provider
pipelineBuilder.UseWhen
(
    (sp) => sp.GetRequiredService<PipelineConditionTrue>(),
    builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>()),
    (sp) => sp.GetRequiredService<IAsyncPipelineBuilder<int, int>>()
);

// condition and branch pipeline builder are provided by the service provider
pipelineBuilder.UseWhen<PipelineConditionTrue>(builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>()));

<br/>

BranchWhen

BranchWhen adds the pipeline branch with its configuration that is executed when the condition is met.

When the condition is met the branch is executed and the main pipeline is NOT executed.

When the condition is NOT met the branch is skipped and the main pipeline is executed.

The target should be set for the pipeline branch.

The pipeline branch is configured using the new pipeline builder instance and configuration delegate.

Example (condition delegate - predicate):

// branch pipeline builder is provided by the factory
pipelineBuilder.BranchWhen
(
    (param) => Task.FromResult(param == -1),
    builder => builder.Use(() => new PipelineStep()).UseTarget((param, cancellationToken) => Task.FromResult(param - 2)),
    () => new AsyncPipelineBuilder<int, int>(serviceProvider)
);

// branch pipeline builder is provided by the factory accepting service provider
pipelineBuilder.BranchWhen
(
    (param) => Task.FromResult(param == -1),
    builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>()).UseTarget((param, cancellationToken) => Task.FromResult(param - 2)),
    (sp) => sp.GetRequiredService<IAsyncPipelineBuilder<int, int>>()
);

// branch pipeline builder is provided by the service provider
pipelineBuilder.BranchWhen
(
    (param) => Task.FromResult(param == -1),
    builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>()).UseTarget((param, cancellationToken) => Task.FromResult(param - 2))
);

<br/>

Example (interface implementation):

public class PipelineConditionTrue : IAsyncPipelineCondition<int>
{
    public Task<bool> Invoke(int param) => Task.FromResult(true);
}

/* ... */

// condition and branch pipeline builder are provided by the factory
pipelineBuilder.BranchWhen
(
    () => new PipelineConditionTrue(),
    builder => builder.Use(() => new PipelineStep()).UseTarget((param, cancellationToken) => Task.FromResult(param - 2)),
    () => new AsyncPipelineBuilder<int, int>(serviceProvider)
);

// condition and branch pipeline builder are provided by the factory accepting service provider
pipelineBuilder.BranchWhen
(
    (sp) => sp.GetRequiredService<PipelineConditionTrue>(),
    builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>()).UseTarget((param, cancellationToken) => Task.FromResult(param - 2)),
    (sp) => sp.GetRequiredService<IAsyncPipelineBuilder<int, int>>()
);

// condition and branch pipeline builder are provided by the service provider
pipelineBuilder.BranchWhen<PipelineConditionTrue>(builder => builder.Use((sp) => sp.GetRequiredService<PipelineStep>()).UseTarget((param, cancellationToken) => Task.FromResult(param - 2)));

Set the pipeline target

The target is the last step executed by the pipeline.

The target should be set for every pipeline or an exception will be thrown during the building of the pipeline.

<br/>

UseTarget

UseTarget is used to set the target of the pipeline.

UseTarget can be called multiple times and the next call will rewrite the target that has been set before.

Example:

public class TargetService
{
    public Task<int> Compute(int param, CancellationToken cancellationToken) => Task.FromResult(param + 1);
}

/* ... */

var service = new TargetService();
pipelineBuilder.UseTarget(service.Compute);

<br/>

Build the pipeline

A pipeline is created (built) using a pipeline builder.

<br/>

BuildPipeline

BuildPipeline builds the pipeline.

Example:

var pipeline = pipelineBuilder.BuildPipeline();

// execute the pipeline
var pipelineResult = await pipeline.Invoke(2, CancellationToken.None);

<br/>

Product Compatible and additional computed target framework versions.
.NET 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 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.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Excellence.Pipelines.Core:

Package Downloads
Excellence.Pipelines

Default implementation of Pipelines.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.0.0 318 12/9/2023
4.0.1 529 11/12/2022
4.0.0 507 11/12/2022
3.0.1 777 9/18/2022
3.0.0 769 6/21/2022
2.0.0 757 5/21/2022
1.0.0 767 5/5/2022