C#中的完全延迟管道

时间:2016-06-24 14:03:42

标签: c# pipeline

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

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

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()方法期间创建。

1 个答案:

答案 0 :(得分:1)

最终解决方案非常简单。我创建了一个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); } } 包装器,这样我仍然可以构建管道但不实例化包装的处理程序,直到它实际需要执行:

jQuery