/// <summary> /// Branches the request pipeline based on the result of the given predicate. /// </summary> /// <param name="app"></param> /// <param name="predicate">Invoked with the request environment to determine if the branch should be taken</param> /// <param name="configuration">Configures a branch to take</param> /// <returns></returns> public static IMiddlewareBuilder <TContext> MapWhen <TContext>(this IMiddlewareBuilder <TContext> app, Predicate <TContext> predicate, Action <IMiddlewareBuilder <TContext> > configuration) where TContext : ContextBase { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } // create branch var branchBuilder = app.New(); configuration(branchBuilder); var branch = branchBuilder.Build(); // put middleware in pipeline var options = new MapWhenOptions <TContext> { Predicate = predicate, Branch = branch, }; return(app.Use(next => new MapWhenMiddleware <TContext>(next, options).Invoke)); }
private static MiddlewareBranch <TContext>[] BuildMiddlewareBranches <TContext>(IMiddlewareBuilder <TContext> parentBuilder, Route <TContext>[] routes) where TContext : Context { if (parentBuilder == null) { throw new ArgumentNullException(nameof(parentBuilder)); } if (routes == null) { throw new ArgumentNullException(nameof(routes)); } return(routes.Select(route => { // setup builder and invoke configuration pipeline var branchBuilder = parentBuilder.New(); // register route context with relevant features (TODO: abstraction layering) foreach (var property in parentBuilder.Properties.Where(x => x.Value is IRouteContextAware <TContext>)) { branchBuilder.Properties.Add(property); var routeContextAware = property.Value as IRouteContextAware <TContext>; routeContextAware.PushRouteContext(route); } route.MiddlewareBuilderForRoute(branchBuilder); // build the stack var branchStack = branchBuilder.Build(); // unregister route context with relevant features foreach (var property in parentBuilder.Properties.Where(x => x.Value is IRouteContextAware <TContext>)) { var routeContextAware = property.Value as IRouteContextAware <TContext>; routeContextAware.PopRouteContext(); } return new MiddlewareBranch <TContext>(route.IsApplicable, branchStack); }).ToArray()); }