/// <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); } }
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())); }
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 } ); }
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); }
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); }