我正在设计一个遵循责任链模式的处理程序管道.
管道处理程序具有以下接口:
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>>这样每个管道处理程序只在调用时创建?
解决方法
最终解决方案非常简单.我创建了一个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); } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。