Advanced Pipeline Patterns

This page demonstrates advanced usage of the Hyperbee Pipeline library, combining extension methods, custom binders, and middleware for powerful and flexible pipeline composition.

Combining Custom Middleware, Extension Methods, and a Binder

Suppose you want to:

  • Add logging to every step (middleware)
  • Add a custom step via an extension method
  • Use a custom binder to control flow (e.g., retry on failure)

Custom Logging Middleware

public static class PipelineMiddleware
{
    public static IPipelineStartBuilder<TStart, TOutput> WithLogging<TStart, TOutput>(this IPipelineStartBuilder<TStart, TOutput> builder)
    {
        return builder.HookAsync(async (ctx, arg, next) =>
        {
            Console.WriteLine($"[LOG] Before: {arg}");
            var result = await next(ctx, arg);
            Console.WriteLine($"[LOG] After: {result}");
            return result;
        });
    }
}

Custom Step via Extension Method

public static class PipelineExtensions
{
    public static IPipelineBuilder<TStart, TOutput> WithCustomTransform<TStart, TOutput>(
        this IPipelineBuilder<TStart, TOutput> builder, Func<TOutput, TOutput> transform)
    {
        return builder.Pipe((ctx, arg) => transform(arg));
    }
}

Custom Retry Binder

public class RetryBinder<TStart, TOutput> : Binder<TStart, TOutput>
{
    private readonly int _maxRetries;
    public RetryBinder(FunctionAsync<TStart, TOutput> function, int maxRetries = 3)
        : base(function, null) => _maxRetries = maxRetries;

    public FunctionAsync<TStart, TOutput> Bind(FunctionAsync<TStart, TOutput> next)
    {
        return async (context, argument) =>
        {
            int attempt = 0;
            while (true)
            {
                try { return await next(context, argument); }
                catch when (++attempt < _maxRetries) { }
            }
        };
    }
}

Usage Example

var pipeline = PipelineFactory
    .Start<string>()
    .WithLogging()
    .Pipe((ctx, arg) => arg + " step1")
    .WithCustomTransform(s => s.ToUpper())
    .Pipe((ctx, arg) => arg + " step2")
    .Pipe((ctx, arg) => throw new Exception("fail"))
    .Pipe((ctx, arg) => new RetryBinder<string, string>(null, 3).Bind((c, a) => Task.FromResult(a)))
    .Build();

var result = await pipeline(new PipelineContext(), "input");

This example demonstrates how to combine middleware, extension methods, and a custom binder for advanced scenarios.


For more, see Extending Pipelines and Middleware.


© Stillpoint Software.