示例#1
0
        /// <summary>
        /// Loads all IController types from the assembly and searches route info in all types.
        /// </summary>
        public void CreateRoutes(Assembly assembly = null)
        {
            RouteBuilder builder = new RouteBuilder();

            Type interfaceType = typeof(IController);

            List <Assembly> assemblies = new List <Assembly>();

            if (assembly == null)
            {
                Assembly entryAssembly = Assembly.GetEntryAssembly();
                if (entryAssembly == null)
                {
                    throw new ArgumentNullException("Entry Assembly could not be found");
                }

                assemblies.Add(entryAssembly);
                assemblies.AddRange(entryAssembly.GetReferencedAssemblies().Select(Assembly.Load));
            }
            else
            {
                assemblies.Add(assembly);
            }

            List <Type> types = assemblies
                                .SelectMany(x => x.GetTypes())
                                .Where(type => interfaceType.IsAssignableFrom(type))
                                .ToList();

            List <RouteLeaf> leaves = new List <RouteLeaf>();

            foreach (Type type in types)
            {
                if (type.IsInterface)
                {
                    continue;
                }

                if (type.IsAssignableFrom(typeof(HorseController)) && typeof(HorseController).IsAssignableFrom(type))
                {
                    continue;
                }

                leaves.AddRange(builder.BuildRoutes(type));
                _services.AddScoped(type);
            }

            foreach (RouteLeaf root in leaves)
            {
                builder.SortChildren(root);
            }

            builder.SortRoutes(leaves);
            foreach (RouteLeaf route in leaves)
            {
                Routes.Add(route);
            }
        }
示例#2
0
        public static IApplicationBuilder UseErrorHandler(this IApplicationBuilder builder, Config config)
        {
            var routes = new RouteBuilder(builder)
            {
                DefaultHandler = builder.ApplicationServices.GetRequiredService <MvcRouteHandler>(),
            };

            routes.BuildRoutes(config);

            return(builder.UseMiddleware <ErrorHandlerMiddleware>(routes.Build()));
        }
示例#3
0
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            RouteBuilder.BuildRoutes(routes);

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                );
        }
示例#4
0
        void IBuilder.Build(IAppBuilder app)
        {
            // Ensure components have unique names
            var componentNames = new SortedList(new CaseInsensitiveComparer());

            foreach (var component in _components)
            {
                component.Name = string.IsNullOrEmpty(component.Middleware.Name)
                    ? Guid.NewGuid().ToShortString(false)
                    : component.Middleware.Name;
                if (componentNames.ContainsKey(component.Name))
                {
                    throw new BuilderException("Middleware component names must be unique."
                                               + " There is more than one component called '" + component.Name
                                               + "'");
                }
                componentNames.Add(component.Name, null);
            }

            // Resolve name only dependencies and fill in the type that they depend on
            foreach (var component in _components)
            {
                foreach (var dependency in component.Middleware.Dependencies)
                {
                    if (dependency.DependentType == null && !string.IsNullOrEmpty(dependency.Name))
                    {
                        var dependent = _components.FirstOrDefault(
                            c => string.Equals(c.Name, dependency.Name, StringComparison.OrdinalIgnoreCase));
                        if (dependent == null)
                        {
                            if (dependency.Required)
                            {
                                throw new MissingDependencyException("There are no middleware components called \"" + dependency.Name + "\"");
                            }
                        }
                        else
                        {
                            dependency.DependentType = dependent.MiddlewareType;
                        }
                    }
                }
            }

            // Split components into routers and other types of middleware
            var routerComponents = _components
                                   .Select(c => c as RouterComponent)
                                   .Where(rc => rc != null)
                                   .ToList();
            var middlewareComponents = _components
                                       .Select(c => c as MiddlewareComponent)
                                       .Where(mc => mc != null)
                                       .ToList();

            var routeBuilder = new RouteBuilder(_dependencyGraphFactory);

            _router = routeBuilder.BuildRoutes(routerComponents);

            if (routerComponents.Count == 1)
            {
                var segment = routerComponents[0].RouterSegments[0];
                foreach (var component in middlewareComponents)
                {
                    component.SegmentAssignments.Add(segment);
                }
            }
            else
            {
                // Split the middleware components into three groups: front, middle and back. Note that routers
                // are always in the middle. Front means run before routing and back means run after routing
                var frontComponents = middlewareComponents
                                      .Where(c => c.Middleware.Dependencies.Any(dep => dep.Position == PipelinePosition.Front))
                                      .ToList();
                var backComponents = middlewareComponents
                                     .Where(c => !frontComponents.Contains(c))
                                     .Where(c => c.Middleware.Dependencies.Any(dep => dep.Position == PipelinePosition.Back))
                                     .ToList();
                var middleComponents = middlewareComponents
                                       .Where(c => !frontComponents.Contains(c))
                                       .Where(c => !backComponents.Contains(c))
                                       .ToList();

                AddToFront(routerComponents, frontComponents);
                AddToMiddle(routerComponents, middleComponents);
                AddToBack(routerComponents, backComponents);
            }

            // Add components to the segments they were assigned to
            foreach (var component in _components)
            {
                foreach (var segment in component.SegmentAssignments)
                {
                    var routingSegment = segment.RoutingSegment;
                    routingSegment.Add(component.Middleware, component.MiddlewareType);
                }
            }

            // Order components within each segment according to their dependencies
            foreach (var routerComponent in routerComponents)
            {
                var router = (IRouter)routerComponent.Middleware;
                foreach (var segment in router.Segments)
                {
                    segment.ResolveDependencies();
                }
            }

            Dump(_router, "");

            app.Use(Invoke);
        }
示例#5
0
        void IBuilder.Build(IAppBuilder app)
        {
            // Ensure components have unique names
            var componentNames = new SortedList(new CaseInsensitiveComparer());

            foreach (var component in _components)
            {
                component.Name = string.IsNullOrEmpty(component.Middleware.Name)
                    ? Guid.NewGuid().ToShortString(false)
                    : component.Middleware.Name;
                if (componentNames.ContainsKey(component.Name))
                {
                    throw new BuilderException("Middleware component names must be unique."
                                               + " There is more than one component called '" + component.Name
                                               + "'");
                }
                componentNames.Add(component.Name, null);
            }

            // Resolve name only dependencies and fill in the type that they depend on
            foreach (var component in _components)
            {
                foreach (var dependency in component.Middleware.Dependencies)
                {
                    var dependencyName = dependency.Name;
                    if (dependency.DependentType == null && !string.IsNullOrEmpty(dependencyName))
                    {
                        var dependent = _components.FirstOrDefault(
                            c => string.Equals(c.Name, dependencyName, StringComparison.OrdinalIgnoreCase));
                        if (dependent == null)
                        {
                            if (dependency.Required)
                            {
                                throw new MissingDependencyException("There are no middleware components called \"" + dependencyName + "\"");
                            }
                        }
                        else
                        {
                            dependency.DependentType = dependent.MiddlewareType;
                        }
                    }
                }
            }

            // Split components into routers and other types of middleware
            var routerComponents = _components
                                   .Select(c => c as RouterComponent)
                                   .Where(rc => rc != null)
                                   .ToList();
            var middlewareComponents = _components
                                       .Select(c => c as MiddlewareComponent)
                                       .Where(mc => mc != null)
                                       .ToList();

            var routeBuilder = new RouteBuilder(_configuration, _dependencyGraphFactory);

            _router = routeBuilder.BuildRoutes(this, routerComponents);

            if (routerComponents.Count == 1)
            {
                var segment = routerComponents[0].RouterSegments[0];
                foreach (var component in middlewareComponents)
                {
                    component.SegmentAssignments.Add(segment);
                }
            }
            else
            {
                // Split the middleware components into three groups: front, middle and back. Note that routers
                // are always in the middle. Front means run before routing and back means run after routing
                var frontComponents = middlewareComponents
                                      .Where(c => c.Middleware.Dependencies.Any(dep => dep.Position == PipelinePosition.Front))
                                      .ToList();
                var backComponents = middlewareComponents
                                     .Where(c => !frontComponents.Contains(c))
                                     .Where(c => c.Middleware.Dependencies.Any(dep => dep.Position == PipelinePosition.Back))
                                     .ToList();
                var middleComponents = middlewareComponents
                                       .Where(c => !frontComponents.Contains(c))
                                       .Where(c => !backComponents.Contains(c))
                                       .ToList();

#if DEBUG
                Action <MiddlewareComponent> p = c =>
                {
                    var l = "   " + c.Name;
                    l += " IMiddleware<" + c.MiddlewareType.Name + ">";
                    l += " {";
                    var sep = "";
                    foreach (var d in c.Middleware.Dependencies)
                    {
                        l  += sep + (d.Required ? "" : "(optional)") + (d.DependentType == null ? "" : d.DependentType.Name) + "[" + d.Name + "]";
                        sep = ", ";
                    }
                    l  += "}";
                    l  += " {";
                    sep = "";
                    foreach (var s in c.SegmentAssignments)
                    {
                        l  += sep + s.Name;
                        sep = ", ";
                    }
                    l += "}";
                    System.Diagnostics.Trace.WriteLine(l);
                };
                System.Diagnostics.Trace.WriteLine("== Before segmentation ==");
                System.Diagnostics.Trace.WriteLine("Components at the front of the pipeline");
                foreach (var c in frontComponents)
                {
                    p(c);
                }
                System.Diagnostics.Trace.WriteLine("Components in the middle of the pipeline");
                foreach (var c in middleComponents)
                {
                    p(c);
                }
                System.Diagnostics.Trace.WriteLine("Components at the back of the pipeline");
                foreach (var c in backComponents)
                {
                    p(c);
                }
#endif

                AddToFront(routerComponents, frontComponents);
                AddToMiddle(routerComponents, middleComponents);
                AddToBack(routerComponents, backComponents);

#if DEBUG
                System.Diagnostics.Trace.WriteLine("== After segmentation ==");
                System.Diagnostics.Trace.WriteLine("Components at the front of the pipeline");
                foreach (var c in frontComponents)
                {
                    p(c);
                }
                System.Diagnostics.Trace.WriteLine("Components in the middle of the pipeline");
                foreach (var c in middleComponents)
                {
                    p(c);
                }
                System.Diagnostics.Trace.WriteLine("Components at the back of the pipeline");
                foreach (var c in backComponents)
                {
                    p(c);
                }
#endif
            }

            // Add components to the segments they were assigned to
            foreach (var component in _components)
            {
                foreach (var segment in component.SegmentAssignments)
                {
                    var routingSegment = segment.RoutingSegment;
                    routingSegment.Add(component.Middleware, component.MiddlewareType);
                }
            }

            // Order components within each segment according to their dependencies
            foreach (var routerComponent in routerComponents)
            {
                var router = (IRouter)routerComponent.Middleware;
                foreach (var segment in router.Segments)
                {
                    segment.ResolveDependencies();
                }
            }

#if DEBUG
            Dump(_router, "");
#endif
            app.Use(Invoke);
        }