/// <summary> /// Добавляет промежуточный класс обработки в конвейер обработки. /// </summary> /// <typeparam name="TMiddleware">Промежуточный класс обработки.</typeparam> /// <typeparam name="T">Тип обрабатываемого объекта.</typeparam> /// <param name="builder"><see cref="IMiddlewareBuilder{T}"/> объект.</param> /// <param name="args">Аргументы передаваемые в конструктор промежуточного класса обработки.</param> /// <returns><see cref="IMiddlewareBuilder{T}"/> объект.</returns> public static IMiddlewareBuilder <T> UseMiddleware <TMiddleware, T>(this IMiddlewareBuilder <T> builder, params object[] args) where TMiddleware : IMiddleware <T> { return(builder.Use(next => { var middleware = typeof(TMiddleware); //Добавляется 1, так как конструктор типа наследуемого от IMiddleware<T> //первым аргументом должен принимать ссылку на следующий делегат var argsLength = args.Length + 1; if (!middleware .GetConstructors() .Any(c => c.GetParameters().Length != 0 && c.GetParameters()[0].ParameterType == typeof(Func <T, Task>) && c.GetParameters().Length.Equals(argsLength))) { throw new InvalidOperationException($"The class [{middleware.Name}] does not have a suitable constructor"); } var methodInfo = middleware.GetMethod(InvokeAsyncMethodName); var ctorArgs = new object[argsLength]; ctorArgs[0] = next; Array.Copy(args, 0, ctorArgs, 1, args.Length); var instance = Activator.CreateInstance(middleware, ctorArgs); return (Func <T, Task>)methodInfo.CreateDelegate(typeof(Func <T, Task>), instance); })); }
//private static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) //{ // while (toCheck != null && toCheck != typeof(object)) // { // var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck; // if (generic == cur) // { // return true; // } // toCheck = toCheck.BaseType; // } // return false; //} private static IMiddlewareBuilder <TContext> UseMiddlewareInterface <TContext>(IMiddlewareBuilder <TContext> app, Type middlewareType) where TContext : ContextBase { return(app.Use(next => { return async context => { var middlewareFactory = (IMiddlewareFactory <TContext>)context.ContextServices.GetService(typeof(IMiddlewareFactory <TContext>)); if (middlewareFactory == null) { // No middleware factory throw new InvalidOperationException("No middleware factory."); } var middleware = middlewareFactory.Create(middlewareType); if (middleware == null) { throw new InvalidOperationException("The factory returned null, it's a broken implementation."); } try { await middleware.InvokeAsync(context, next); } finally { middlewareFactory.Release(middleware); } }; })); }
/// <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)); }
public static IMiddlewareBuilder <TContext> UseRoutes <TContext>(this IMiddlewareBuilder <TContext> self, params Route <TContext>[] routes) where TContext : Context { if (self == null) { throw new ArgumentNullException(nameof(self)); } if (routes == null) { throw new ArgumentNullException(nameof(routes)); } foreach (var route in routes) { if (route.IsApplicable == null) { throw new ArgumentNullException(nameof(route.IsApplicable)); } if (route.MiddlewareBuilderForRoute == null) { throw new ArgumentNullException(nameof(route.MiddlewareBuilderForRoute)); } } return(self.Use(InternalRouter.CreateMiddlewareFactory(self, routes))); }
/// <summary> /// Упрощает добавление промежуточного делегата в конвейер обработки. /// </summary> /// <typeparam name="T">Обрабатываемый тип.</typeparam> /// <param name="builder"><see cref="IMiddlewareBuilder{T}"/> объект.</param> /// <param name="middleware">Функция обрабатывающая запрос или вызывает следующую в конвейере обработки.</param> /// <returns><see cref="IMiddlewareBuilder{T}"/> объект.</returns> public static IMiddlewareBuilder <T> Use <T>(this IMiddlewareBuilder <T> builder, Func <T, Func <Task>, Task> middleware) { return(builder.Use(next => { return item => middleware(item, () => next(item)); })); }
public static IMiddlewareBuilder <TContext> Use <TContext>(this IMiddlewareBuilder <TContext> app, Func <TContext, Func <Task>, Task> middleware) where TContext : ContextBase { return(app.Use(next => { return context => { Func <Task> simpleNext = () => next(context); return middleware(context, simpleNext); }; })); }
public static IMiddlewareBuilder <TContext> UseMiddleware <TContext>(this IMiddlewareBuilder <TContext> builder, Type middleware, params object[] args) where TContext : ContextBase { if (typeof(IMiddleware <TContext>).GetTypeInfo().IsAssignableFrom(middleware.GetTypeInfo())) { if (args.Length > 0) { throw new NotSupportedException("IMiddleware doesn't support passing args directly since it's"); } return(UseMiddlewareInterface(builder, middleware)); } var applicationServices = builder.ApplicationServices; return(builder.Use(next => { var methods = middleware.GetMethods(BindingFlags.Instance | BindingFlags.Public); var invokeMethods = methods.Where(m => string.Equals(m.Name, InvokeMethodName, StringComparison.Ordinal) || string.Equals(m.Name, InvokeAsyncMethodName, StringComparison.Ordinal) ).ToArray(); if (invokeMethods.Length > 1) { throw new InvalidOperationException($"Find over then one invoke methode."); } if (invokeMethods.Length == 0) { throw new InvalidOperationException("Can't find invoke methode."); } var methodInfo = invokeMethods[0]; if (!typeof(Task).IsAssignableFrom(methodInfo.ReturnType)) { throw new InvalidOperationException($"Invoke methode must return Task."); } var parameters = methodInfo.GetParameters(); if (parameters.Length == 0 || parameters[0].ParameterType.BaseType != typeof(ContextBase)) { throw new InvalidOperationException($"Can't find methode {InvokeMethodName} or {InvokeAsyncMethodName} with parameters"); } var ctorArgs = new object[args.Length + 1]; ctorArgs[0] = next; Array.Copy(args, 0, ctorArgs, 1, args.Length); var instance = ActivatorUtilities.CreateInstance(builder.ApplicationServices, middleware, ctorArgs); if (parameters.Length == 1) { return (MiddlewareDelegate <TContext>)methodInfo.CreateDelegate(typeof(MiddlewareDelegate <TContext>), instance); } var factory = Compile <object, TContext>(methodInfo, parameters); return context => { var serviceProvider = context.ContextServices ?? applicationServices; if (serviceProvider == null) { throw new InvalidOperationException("ServiceProvider not available."); } return factory(instance, context, serviceProvider); }; })); }
public static IMiddlewareBuilder <TContext> Use <TContext>(this IMiddlewareBuilder <TContext> self, IMiddleware <TContext> middleware) where TContext : Context => self.Use(middleware.InvokeAsync);
public static IMiddlewareBuilder <TContext> Run <TContext>(this IMiddlewareBuilder <TContext> self, MiddlewareDelegate <TContext> handler) where TContext : Context => self.Use(next => handler);
public static IMiddlewareBuilder <TContext> Use <TContext>(this IMiddlewareBuilder <TContext> self, MiddlewareDelegate <TContext> middleware) where TContext : Context => self.Use(next => async context => { await middleware(context); await next(context); });
public static IMiddlewareBuilder <TContext> Use <TContext>(this IMiddlewareBuilder <TContext> self, Func <TContext, MiddlewareDelegate <TContext>, Task> middleware) where TContext : Context => self.Use(factoryInputNext => { return(context => middleware(context, factoryInputNext)); });
public static void Run <TContext>(this IMiddlewareBuilder <TContext> app, MiddlewareDelegate <TContext> handler) where TContext : ContextBase { app.Use(_ => handler); }
public static IMiddlewareBuilder <TContext> UseJsonSerializer <T, TContext>(this IMiddlewareBuilder <TContext> self, Func <TContext, string> contentSelector, string argumentName) where TContext : Context { return(self.Use(JsonArgumentSerializer.CreateMiddlewareFactoryForJsonSerializer <T, TContext>(contentSelector, argumentName))); }
public static IMiddlewareBuilder <TContext> UseRoutingKey <TContext>(this IMiddlewareBuilder <TContext> self, Func <TContext, string> routingKeySelector, params string[] routePatterns) where TContext : Context { return(self.Use(StringRouter.CreateRoutingKeyMiddlewareFactory <TContext>(routingKeySelector, routePatterns))); }
public static IMiddlewareBuilder <TContext> UseRouting <TContext>(this IMiddlewareBuilder <TContext> self) where TContext : Context => self.Use(EndpointRouter.CreateRoutingSetupMiddlewareFactory(self));
public static IMiddlewareBuilder <TContext> UseEndpoints <TContext>(this IMiddlewareBuilder <TContext> self, Action <IEndpointRouteBuilder <TContext> > endpoints) where TContext : Context => self.Use(EndpointRouter.CreateEndpointDispatcherMiddlewareFactory(self, endpoints));