public override Matcher Build()
        {
            var builder = new TreeRouteBuilder(
                NullLoggerFactory.Instance,
                new DefaultObjectPool <UriBuildingContext>(new UriBuilderContextPooledObjectPolicy()),
                new DefaultInlineConstraintResolver(Options.Create(new RouteOptions()), new TestServiceProvider()));

            var selector = new DefaultEndpointSelector();

            var groups = _endpoints
                         .GroupBy(e => (e.Order, e.RoutePattern.InboundPrecedence, e.RoutePattern.RawText))
                         .OrderBy(g => g.Key.Order)
                         .ThenBy(g => g.Key.InboundPrecedence);

            var routes = new RouteCollection();

            foreach (var group in groups)
            {
                var candidates = group.ToArray();

                // RouteEndpoint.Values contains the default values parsed from the template
                // as well as those specified with a literal. We need to separate those
                // for legacy cases.
                var endpoint = group.First();
                var defaults = new RouteValueDictionary(endpoint.RoutePattern.Defaults);
                for (var i = 0; i < endpoint.RoutePattern.Parameters.Count; i++)
                {
                    var parameter = endpoint.RoutePattern.Parameters[i];
                    if (parameter.Default != null)
                    {
                        defaults.Remove(parameter.Name);
                    }
                }

                builder.MapInbound(
                    new SelectorRouter(selector, candidates),
                    new RouteTemplate(endpoint.RoutePattern),
                    routeName: null,
                    order: endpoint.Order);
            }

            return(new TreeRouterMatcher(builder.Build()));
        }
Beispiel #2
0
        internal override Matcher CreateMatcher(MatcherEndpoint endpoint)
        {
            var builder = new TreeRouteBuilder(
                NullLoggerFactory.Instance,
                new DefaultObjectPool <UriBuildingContext>(new UriBuilderContextPooledObjectPolicy()),
                new DefaultInlineConstraintResolver(Options.Create(new RouteOptions())));

            var handler = new RouteHandler(c =>
            {
                var feature      = c.Features.Get <IEndpointFeature>();
                feature.Endpoint = endpoint;
                feature.Invoker  = MatcherEndpoint.EmptyInvoker;

                return(Task.CompletedTask);
            });

            builder.MapInbound(handler, TemplateParser.Parse(endpoint.Template), "default", 0);

            return(new TreeRouterMatcher(builder.Build()));
        }
Beispiel #3
0
        // internal for testing
        internal void AddEntries(TreeRouteBuilder builder, ActionDescriptorCollection actions)
        {
            var routeInfos = GetRouteInfos(actions.Items);

            // We're creating one TreeRouteLinkGenerationEntry per action. This allows us to match the intended
            // action by expected route values, and then use the TemplateBinder to generate the link.
            foreach (var routeInfo in routeInfos)
            {
                builder.MapOutbound(
                    _handler,
                    routeInfo.RouteTemplate,
                    new RouteValueDictionary(routeInfo.ActionDescriptor.RouteValueDefaults),
                    routeInfo.RouteName,
                    routeInfo.Order);
            }

            // We're creating one AttributeRouteMatchingEntry per group, so we need to identify the distinct set of
            // groups. It's guaranteed that all members of the group have the same template and precedence,
            // so we only need to hang on to a single instance of the RouteInfo for each group.
            var distinctRouteInfosByGroup = GroupRouteInfosByGroupId(routeInfos);

            foreach (var routeInfo in distinctRouteInfosByGroup)
            {
                // Note that because we only support 'inline' defaults, each routeInfo group also has the same
                // set of defaults.
                //
                // We then inject the route group as a default for the matcher so it gets passed back to MVC
                // for use in action selection.
                var entry = builder.MapInbound(
                    _handler,
                    routeInfo.RouteTemplate,
                    routeInfo.RouteName,
                    routeInfo.Order);

                entry.Defaults[TreeRouter.RouteGroupKey] = routeInfo.RouteGroup;
            }
        }