C#中的完全延迟管道

我正在设计一个遵循责任链模式的处理程序管道.

管道处理程序具有以下接口:

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

每个处理程序都引用了管道中的下一个处理程序.以下类用于构建管道:

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;
    }
}

当前实现的缺点是管道中的每个处理程序都是预先构建的.我想按需构造每个处理程序,而不是将处理程序实例传递给构建,而是传递一个Func< IPipelineHandler< TContext>>.

我需要对Build()进行哪些修改才能使用Func< IPipelineHandler< TContext>>这样每个管道处理程序只在调用时创建?

如果不清楚 – 每个处理程序只应在管道中的前一个处理程序调用时创建,而不是在Build()方法期间创建.

最佳答案 最终解决方案非常简单.我创建了一个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);
    }
}
点赞