Complete lazy pipeline in C #

I am developing a handler pipeline that follows a responsibility chain pattern.

The pipeline handler has the following interface:

public interface IPipelineHandler<TContext>
{
    Func<TContext, Task> Next { get; set; }
    Task HandleAsync(TContext context);
}

Each handler has a link to the next handler in the pipeline. The following class is used to build the pipeline:

public class PipelineBuilder<TContext>
{
    private readonly List<IPipelineHandler<TContext>> handlers
        = new List<IPipelineHandler<TContext>>();

    public PipelineBuilder<TContext> Register(IPipelineHandler<TContext> handler)
    {
        handlers.Add(handler);
        return this;
    }

    public Func<TContext, Task> Build()
    {
        IPipelineHandler<TContext> root = null;
        IPipelineHandler<TContext> prev = null;

        foreach (var handler in handlers)
        {
            if (root == null)
            {
                root = handler;
            }
            else
            {
                prev.Next = ctx => handler.HandleAsync(ctx);
            }

            prev = handler;
        }

        return root.HandleAsync;
    }
}

The disadvantage of the current implementation is that each handler in the pipeline is designed in advance. I would like to build each handler on demand, so instead of passing the instance of the handler to the assembly, you pass Func<IPipelineHandler<TContext>>.

What modification needs to be done to Build()work with Func<IPipelineHandler<TContext>>so that each pipeline handler is created only when called?

- , , Build().

+4
1

. LazyPipelineHandler, , , :

public class LazyPipelineHandler<TContext> : PipelineHandler<TContext>
{
    private readonly Lazy<IPipelineHandler<TContext>> innerHandler;

    public LazyPipelineHandler(Func<IPipelineHandler<TContext>> handlerFactory) 
    {
        this.innerHandler = new Lazy<IPipelineHandler<TContext>>(handlerFactory);
    }

    public override Task HandleAsync(TContext context, Func<TContext, Task> next) 
    {
        innerHandler.Value.Next = next;
        return innerHandler.Value.HandleAsync(context);
    }
}
+1

All Articles