예제 #1
0
        /// <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));
        }
예제 #2
0
 public MiddlewareRegistration(IMiddlewareBuilder middlewareBuilder, MiddlewareStage stage, int priority, int index)
 {
     this.MiddlewareBuilder = middlewareBuilder;
     this.Stage             = stage;
     this.Priority          = priority;
     this.Index             = index;
 }
        /// <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);
            }));
        }
        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)));
        }
예제 #5
0
        /// <summary>
        /// Uses the given <see cref="IMiddlewareBuilder" />, placing it at the end of the
        /// current list and adding the assembly from where it comes from as a reference.
        /// </summary>
        /// <remarks>
        /// This method is not normally used directly, as the building is directed by the options
        /// present in <see cref="BlueprintApiOptions" />.
        /// </remarks>
        /// <param name="middlewareBuilder">The builder to add, must not be <c>null</c>.</param>
        private void Use(IMiddlewareBuilder middlewareBuilder)
        {
            Guard.NotNull(nameof(middlewareBuilder), middlewareBuilder);

            this._builders.Add(middlewareBuilder);
            this._references.Add(middlewareBuilder.GetType().Assembly);
        }
예제 #6
0
 /// <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 void MapWhenException(
     IMiddlewareBuilder <CFTFileContext> middlewareBuilder,
     IConfigurationSection mapWhenExceptionOptions)
 {
     MapWhenException(
         middlewareBuilder,
         mapWhenExceptionOptions.Get <MapWhenExceptionOptions>());
 }
 public IMiddlewareBuilder <CFTFileContext> ConfigureApplication(
     IMiddlewareBuilder <CFTFileContext> middlewareBuilder,
     IConfigurationSection stepOptions)
 {
     return(ConfigureApplication(
                middlewareBuilder,
                stepOptions.Get <IEnumerable <StepOptions> >()));
 }
 public void MapWhenRegExpFileName(
     IMiddlewareBuilder <CFTFileContext> middlewareBuilder,
     IConfigurationSection mapWhenFileNameOptions)
 {
     MapWhenRegExpFileName(
         middlewareBuilder,
         mapWhenFileNameOptions.Get <MapWhenFileNameOptions>());
 }
예제 #10
0
 /// <summary>
 /// Шаг проверки файла по XSD схеме.
 /// </summary>
 /// <param name="app">Сборщик мидлвар.</param>
 /// <param name="configSection">настройки для мидлвары</param>
 /// <returns>Сборщик мидлвар с добавленным шагом проверки по схеме.</returns>
 public static IMiddlewareBuilder <CFTFileContext> UseValidationXSD(
     this IMiddlewareBuilder <CFTFileContext> app,
     IConfigurationSection configSection)
 {
     return(app.UseValidationXSD(options =>
     {
         configSection.Bind(options);
     }));
 }
예제 #11
0
 public static IMiddlewareBuilder <CFTFileContext> UseTransformXSLT(
     this IMiddlewareBuilder <CFTFileContext> app,
     IConfigurationSection configSection)
 {
     return(app.UseTransformXSLT(options =>
     {
         configSection.Bind(options);
     }));
 }
예제 #12
0
        /// <summary>
        /// Шаг проверки файла по XSD схеме.
        /// </summary>
        /// <param name="app">Сборщик мидлвар.</param>
        /// <param name="configOption">настройки для мидлвары</param>
        /// <returns>Сборщик мидлвар с добавленным шагом проверки по схеме.</returns>
        public static IMiddlewareBuilder <CFTFileContext> UseValidationXSD(
            this IMiddlewareBuilder <CFTFileContext> app,
            Action <ValidateByXSDOptions> configOption)
        {
            var options = new ValidateByXSDOptions();

            configOption(options);
            app.UseMiddleware <ValidateByXSDMiddleWare, CFTFileContext>(options);
            return(app);
        }
예제 #13
0
        public static IMiddlewareBuilder <CFTFileContext> UseTransformFileName(
            this IMiddlewareBuilder <CFTFileContext> app,
            Action <FileNameTransformOptions> configOption)
        {
            var options = new FileNameTransformOptions();

            configOption(options);
            app.UseMiddleware <FileNameTransformMiddleWare, CFTFileContext>(options);
            return(app);
        }
예제 #14
0
        public static IMiddlewareBuilder <CFTFileContext> UseTransformXSLT(
            this IMiddlewareBuilder <CFTFileContext> app,
            Action <XSLTransformContentOptions> configOption)
        {
            var options = new XSLTransformContentOptions();

            configOption(options);
            app.UseMiddleware <XSLTransformContentMiddleWare, CFTFileContext>(options);
            return(app);
        }
예제 #15
0
        public static IMiddlewareBuilder <CFTFileContext> UseRemove(
            this IMiddlewareBuilder <CFTFileContext> app,
            Action <RemoveFileOptions> configOption)
        {
            var options = new RemoveFileOptions();

            configOption(options);
            app.UseMiddleware <RemoveFileMiddleWare, CFTFileContext>(options);
            return(app);
        }
예제 #16
0
 public void MapWhenException(
     IMiddlewareBuilder <CFTFileContext> middlewareBuilder,
     MapWhenExceptionOptions options)
 {
     if (options == null)
     {
         throw new ArgumentNullException(nameof(options), "Отсутствуют настройки для секции обработки ошибок.");
     }
     options?.ValidationParams();
     middlewareBuilder.MapWhenException(
         builder => this.ConfigureApplication(builder, options.Steps));
 }
예제 #17
0
 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);
         };
     }));
 }
예제 #18
0
 public void MapWhenRegExpFileName(
     IMiddlewareBuilder <CFTFileContext> middlewareBuilder,
     MapWhenFileNameOptions options)
 {
     if (options == null)
     {
         throw new ArgumentNullException(nameof(options), "Отсутствуют настройки для секции определения имени файла.");
     }
     options.ValidationParams();
     middlewareBuilder.MapWhen(
         ctx => Regex.Match(ctx.InputFile.FileName, options.Mask).Success,
         builder => this.ConfigureApplication(builder, options.Steps));
 }
예제 #19
0
 public Task InitializeAsync(IMiddlewareBuilder builder)
 {
     Task.Factory
     .StartNew(SendMessages)
     .ContinueWith(result =>
     {
         if (result.Exception != null)
         {
             _logger.Error(result.Exception);
         }
     },
                   TaskContinuationOptions.OnlyOnFaulted);
     return(Task.CompletedTask);
 }
예제 #20
0
        public IMiddlewareBuilder <CFTFileContext> ConfigureApplication(
            IMiddlewareBuilder <CFTFileContext> middlewareBuilder,
            IEnumerable <StepOptions> stepsOptions)
        {
            foreach (var stepOption in stepsOptions)
            {
                switch (stepOption.Type)
                {
                case StepType.MapWhenException:
                    MapWhenException(middlewareBuilder, stepOption.Settings);
                    break;

                case StepType.MapWhenFileName:
                    MapWhenRegExpFileName(middlewareBuilder, stepOption.Settings);
                    break;

                case StepType.XSDValidation:
                    middlewareBuilder.UseValidationXSD(stepOption.Settings);
                    break;

                case StepType.FileNameTransformation:
                    middlewareBuilder.UseTransformFileName(stepOption.Settings);
                    break;

                case StepType.XSLTransformation:
                    middlewareBuilder.UseTransformXSLT(stepOption.Settings);
                    break;

                case StepType.Export:
                    middlewareBuilder.UseExport(stepOption.Settings);
                    break;
                }
            }

            middlewareBuilder.UseRemove(option =>
            {
                option.FileProviderType     = _scanFileProviderType;
                option.FileProviderSettings = _scanFileProviderSettings;
                option.FileType             = RemoveFileType.Input;
            });

            return(middlewareBuilder);
        }
예제 #21
0
        public static Func <MiddlewareDelegate <TContext>, MiddlewareDelegate <TContext> > CreateMiddlewareFactory <TContext>(IMiddlewareBuilder <TContext> self, Route <TContext>[] routes) where TContext : Context
        {
            // as part of the builder for the routing step, built the middleware stacks for each branch
            var branches = BuildMiddlewareBranches(self, routes);

            return(BranchMiddlewareFactory);

            // integrate a middleware which selects the built branches based on their predicate.
            MiddlewareDelegate <TContext> BranchMiddlewareFactory(MiddlewareDelegate <TContext> next)
            {
                return(CreateMiddleware(next, branches));
            }
        }
예제 #22
0
 private void Add(IMiddlewareBuilder middleware, MiddlewareStage middlewareStage, int priority)
 {
     this._middlewareStages.Add(new MiddlewareRegistration(middleware, middlewareStage, priority, this._middlewareStages.Count));
 }
예제 #23
0
        public PipelineBuilder AddMiddleware(IMiddlewareBuilder builder, MiddlewareStage middlewareStage)
        {
            this.Add(builder, middlewareStage, 0);

            return(this);
        }
예제 #24
0
 public Task InitializeAsync(IMiddlewareBuilder builder) => Task.CompletedTask;
예제 #25
0
        public static Func <MiddlewareDelegate <TContext>, MiddlewareDelegate <TContext> > CreateEndpointDispatcherMiddlewareFactory <TContext>(IMiddlewareBuilder <TContext> middlewareBuilder, Action <IEndpointRouteBuilder <TContext> > configure) where TContext : Context
        {
            if (middlewareBuilder is null)
            {
                throw new ArgumentNullException(nameof(middlewareBuilder));
            }

            if (configure is null)
            {
                throw new ArgumentNullException(nameof(configure));
            }

            var endpointDispatcherId = Guid.NewGuid();

            var endpointRouteBuilder = EnsureEndpointRouteBuilder(middlewareBuilder);

            // each UseEndpoints only executes the endpoints withing the provided configuration and skip all other endpoints. If queried outside of local configuration, return the element
            endpointRouteBuilder.PushPredicateContext(context => context.Feature <EndpointDispatcherScope>()?.DispatcherId is null || context.Feature <EndpointDispatcherScope>()?.DispatcherId == endpointDispatcherId);
            configure(endpointRouteBuilder);
            endpointRouteBuilder.PopPredicateContext();
            endpointRouteBuilder.UpdateEndpointRoutes();

            return(EndpointDispatcherMiddlewareFactory);

            MiddlewareDelegate <TContext> EndpointDispatcherMiddlewareFactory(MiddlewareDelegate <TContext> next)
            {
                var endpointRoutes = endpointRouteBuilder.EndpointRoutes;

                return(EndpointDispatcherMiddleware);

                async Task EndpointDispatcherMiddleware(TContext context)
                {
                    var feature = EnsureEndpointFeature(context, endpointRoutes);

                    // select only endpoints in the current configuration
                    context.Features.Set(new EndpointDispatcherScope()
                    {
                        DispatcherId = endpointDispatcherId
                    });

                    if (feature.TryGetEndpoint(context, out var endpoint))
                    {
                        context.Features.Set <EndpointDispatcherScope>(null);

                        await endpoint.MiddlewareDelegate(context);
                    }
                    // if no endpoint is found, continue the middleware stack
                    else
                    {
                        context.Features.Set <EndpointDispatcherScope>(null);

                        await next(context);
                    }
                }
            }
        }
예제 #26
0
        public static Func <MiddlewareDelegate <TContext>, MiddlewareDelegate <TContext> > CreateRoutingSetupMiddlewareFactory <TContext>(IMiddlewareBuilder <TContext> middlewareBuilder) where TContext : Context
        {
            if (middlewareBuilder is null)
            {
                throw new ArgumentNullException(nameof(middlewareBuilder));
            }

            // Setup the endpoint route builder
            var endpointRouteBuilder = EnsureEndpointRouteBuilder(middlewareBuilder);

            endpointRouteBuilder.UpdateEndpointRoutes();

            // return the factory
            return(RoutingSetupMiddlewareFactory);

            MiddlewareDelegate <TContext> RoutingSetupMiddlewareFactory(MiddlewareDelegate <TContext> next)
            {
                var endpointRoutes = endpointRouteBuilder.EndpointRoutes;

                return(RoutingSetupMiddleware);

                async Task RoutingSetupMiddleware(TContext context)
                {
                    AddEndpointFeature(context, endpointRoutes);

                    await next(context);
                }
            }
        }
예제 #27
0
        private static DefaultEndpointRouteBuilder <TContext> EnsureEndpointRouteBuilder <TContext>(IMiddlewareBuilder <TContext> middlewareBuilder) where TContext : Context
        {
            if (middlewareBuilder is null)
            {
                throw new ArgumentNullException(nameof(middlewareBuilder));
            }

            if (!middlewareBuilder.Properties.TryGetValue(DefaultEndpointRouteBuilder <TContext> .PropertyName, out var endpointRouteBuilder))
            {
                endpointRouteBuilder = new DefaultEndpointRouteBuilder <TContext>(middlewareBuilder.ServiceProvider);

                middlewareBuilder.Properties.Add(DefaultEndpointRouteBuilder <TContext> .PropertyName, endpointRouteBuilder);
            }

            return(endpointRouteBuilder as DefaultEndpointRouteBuilder <TContext>);
        }
예제 #28
0
        //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);
                    }
                };
            }));
        }
예제 #29
0
 public static IMiddlewareBuilder <TContext> UseMiddleware <TMiddleware, TContext>(this IMiddlewareBuilder <TContext> builder, params object[] args)
     where TContext : ContextBase
 {
     return(builder.UseMiddleware <TContext>(typeof(TMiddleware), args));
 }
예제 #30
0
        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);
                };
            }));
        }