Last active
March 3, 2016 09:50
-
-
Save khellang/bd59065433ee450a9cc2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Threading.Tasks; | |
| public delegate Task AppFunc(IDictionary<string, object> env); | |
| public delegate AppFunc MidFunc(AppFunc next); | |
| public delegate MidFunc MidFactoryFunc(IDictionary<string, object> props); | |
| public delegate void BuildFunc(MidFactoryFunc factory); | |
| public static class Program | |
| { | |
| public static void Main() | |
| { | |
| var factories = new Stack<MidFactoryFunc>(); | |
| Configure(factories.Push); | |
| var middleware = BuildMiddleware(factories); | |
| var app = ComposePipeline(middleware); | |
| ListenForRequests(app); | |
| // Result: | |
| // ClassMiddleware: Begin | |
| // FunctionMiddleware: Begin | |
| // FunctionMiddleware: End | |
| // ClassMiddleware: End | |
| } | |
| private static void Configure(BuildFunc builder) | |
| { | |
| builder.UseClassMiddleware(); | |
| builder.UseFunctionMiddleware(); | |
| } | |
| private static IEnumerable<MidFunc> BuildMiddleware(IEnumerable<MidFactoryFunc> factories) | |
| { | |
| var props = new Dictionary<string, object>(); | |
| // Build the middleware using the startup properties. | |
| return factories.Select(factory => factory(props)).ToArray(); | |
| } | |
| private static AppFunc ComposePipeline(IEnumerable<MidFunc> middleware) | |
| { | |
| var end = new AppFunc(_ => Task.FromResult(0)); | |
| // Build our pipeline. The last AppFunc is terminating. | |
| return middleware.Aggregate(end, (current, next) => next(current)); | |
| } | |
| private static void ListenForRequests(AppFunc app) | |
| { | |
| var hasRequest = true; | |
| while (hasRequest) | |
| { | |
| var env = new Dictionary<string, object>(); | |
| app(env); // Invoke our pipeline using the environment. | |
| hasRequest = string.IsNullOrEmpty(Console.ReadLine()); | |
| } | |
| } | |
| } | |
| public static class MiddlewareBuilderExtensions | |
| { | |
| public static void UseClassMiddleware(this BuildFunc builder) | |
| { | |
| builder(props => next => new ClassMiddleware(next).Invoke); | |
| } | |
| public static void UseFunctionMiddleware(this BuildFunc builder) | |
| { | |
| builder(props => next => async env => | |
| { | |
| Console.WriteLine("FunctionMiddleware: Begin"); | |
| await next(env); | |
| Console.WriteLine("FunctionMiddleware: End"); | |
| }); | |
| } | |
| } | |
| public class ClassMiddleware | |
| { | |
| public ClassMiddleware(AppFunc next) | |
| { | |
| Next = next; | |
| } | |
| private AppFunc Next { get; } | |
| public async Task Invoke(IDictionary<string, object> env) | |
| { | |
| Console.WriteLine("ClassMiddleware: Begin"); | |
| await Next(env); | |
| Console.WriteLine("ClassMiddleware: End"); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment