public interface IStepContext
{
}
public class StepContext : IStepContext
{
}
using System.Threading.Tasks;
public delegate Task StepDelegate(IStepContext context);
using System.Threading.Tasks;
public interface IPipelineBuilder
{
IPipelineBuilder Use(Func, Task> step);
IPipelineBuilder Use(Func step);
StepDelegate Build();
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class PipelineBuilder : IPipelineBuilder
{
private readonly IList> _components = null;
private bool _builded = false;
public PipelineBuilder()
{
this._components = new List>();
}
public StepDelegate Build()
{
if (_builded) throw new InvalidOperationException("Build can only once");
_builded = true;
StepDelegate step = context =>
{
Console.WriteLine($"Warning: you didn't provide an endpoint on {DateTime.Now:yyyy/MM/dd HH:mm:ss.fff}"); ;
return Task.CompletedTask;
};
foreach (var component in _components.Reverse())
{
step = component(step);
}
_components.Clear();
return step;
}
public IPipelineBuilder Use(Func, Task> step)
{
return Use(next =>
{
return context =>
{
Task nextTask() => next(context); // Task nextTask() { return next(context); };
return step(context, nextTask);
};
});
}
public IPipelineBuilder Use(Func step)
{
this._components.Add(step);
return this;
}
}
using System;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
IPipelineBuilder pipelineBuilder = new PipelineBuilder();
IStepContext stepContext = new StepContext();
pipelineBuilder.Use(async (context, next) =>
{
Console.WriteLine("第一步开始");
await next();
Console.WriteLine("第一步结束");
});
pipelineBuilder.Use(async (context, next) =>
{
Console.WriteLine("第二步开始");
await next();
Console.WriteLine("第二步结束");
}).Use(async (context, next) =>
{
Console.WriteLine("第三步开始");
await next();
Console.WriteLine("第三步结束");
});
pipelineBuilder.Use((context, next) =>
{
Console.WriteLine("第四步终结点");
return Task.CompletedTask;
});
var pipeline = pipelineBuilder.Build();
pipeline(stepContext).Wait();
}
}