Child Pipelines

The PipelineFactory library allows you to use pipelines together. Since pipelines are just functions (FunctionAsync<TStart, TOutput>), they can be used as input to other pipelines. This allows you to create complex data processing flows by reusing and chaining together multiple pipelines.

Each child pipeline is itself a Kleisli arrow – its own TStart is the parent pipeline’s current TOutput. This is the self-similar composition at the heart of the pipeline’s monadic design.

Here is an example of how to use pipelines together:

// pipeline2: TStart=string, TOutput=string
var pipeline2 = PipelineFactory
    .Start<string>()
    .Pipe( ( ctx, arg ) => $"{arg} again!" )
    .Build();

// pipeline1: TStart=string, TOutput=string
// PipeAsync feeds pipeline1's TOutput (string) as pipeline2's TStart (string)
var pipeline1 = PipelineFactory
    .Start<string>()
    .Pipe( ( ctx, arg ) => $"hello {arg}" )
    .PipeAsync( pipeline2 )
    .Build();

var result = await pipeline1( new PipelineContext(), "you" );

Assert.AreEqual( "hello you again!", result );

Composing Commands

Commands are injectable wrappers around pipelines. You can compose a command’s pipeline directly into another pipeline using PipeAsync, CallAsync, PipeIf, or CallIf. The command’s pipeline is used as a step – the pipeline context flows through without creating a new context.

// commandB is an ICommandFunction<string, string> injected via DI

var pipeline = PipelineFactory
    .Start<string>()
    .Pipe( ( ctx, arg ) => $"hello {arg}" )
    .PipeAsync( commandB )          // compose command's pipeline
    .Build();

See Commands for more details.


© Stillpoint Software.

Hyperbee Pipeline Docs