private ApiDescriptionGroupCollection GetCollection(ActionDescriptorCollection actionDescriptors)
        {
            var context = new ApiDescriptionProviderContext(actionDescriptors.Items);

            foreach (var provider in _apiDescriptionProviders)
            {
                provider.OnProvidersExecuting(context);
            }

            for (var i = _apiDescriptionProviders.Length - 1; i >= 0; i--)
            {
                _apiDescriptionProviders[i].OnProvidersExecuted(context);
            }

            var groups = context.Results
                .GroupBy(d => d.GroupName)
                .Select(g => new ApiDescriptionGroup(g.Key, g.ToArray()))
                .ToArray();

            return new ApiDescriptionGroupCollection(groups, actionDescriptors.Version);
        }
예제 #2
0
        private static IServiceProvider CreateServices(params ActionDescriptor[] actions)
        {
            var collection = new ActionDescriptorCollection(actions, version: 0);

            var actionDescriptorProvider = new Mock<IActionDescriptorCollectionProvider>();
            actionDescriptorProvider
                .Setup(a => a.ActionDescriptors)
                .Returns(collection);

            var routeOptions = new Mock<IOptions<RouteOptions>>();
            routeOptions
                .SetupGet(o => o.Value)
                .Returns(new RouteOptions());

            return new ServiceCollection()
                .AddSingleton<IInlineConstraintResolver>(new DefaultInlineConstraintResolver(routeOptions.Object))
                .AddSingleton<UrlEncoder>(new UrlTestEncoder())
                .AddRouting()
                .AddSingleton(actionDescriptorProvider.Object)
                .AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance)
                .BuildServiceProvider();
        }
예제 #3
0
        private TreeRouter BuildRoute(ActionDescriptorCollection actions)
        {
            var routeBuilder = new TreeRouteBuilder(_target, _loggerFactory);
            var routeInfos = GetRouteInfos(_constraintResolver, actions.Items);

            // We're creating one AttributeRouteGenerationEntry 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)
            {
                routeBuilder.Add(new TreeRouteLinkGenerationEntry()
                {
                    Binder = new TemplateBinder(_urlEncoder, _contextPool, routeInfo.ParsedTemplate, routeInfo.Defaults),
                    Defaults = routeInfo.Defaults,
                    Constraints = routeInfo.Constraints,
                    Order = routeInfo.Order,
                    GenerationPrecedence = routeInfo.GenerationPrecedence,
                    RequiredLinkValues = routeInfo.ActionDescriptor.RouteValueDefaults,
                    RouteGroup = routeInfo.RouteGroup,
                    Template = routeInfo.ParsedTemplate,
                    Name = routeInfo.Name,
                });
            }

            // 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)
            {
                routeBuilder.Add(new TreeRouteMatchingEntry()
                {
                    Order = routeInfo.Order,
                    Precedence = routeInfo.MatchPrecedence,
                    Target = _target,
                    RouteName = routeInfo.Name,
                    RouteTemplate = TemplateParser.Parse(routeInfo.RouteTemplate),
                    TemplateMatcher = new TemplateMatcher(
                        routeInfo.ParsedTemplate,
                        new RouteValueDictionary(StringComparer.OrdinalIgnoreCase)
                        {
                            { TreeRouter.RouteGroupKey, routeInfo.RouteGroup }
                        }),
                    Constraints = routeInfo.Constraints
                });
            }

            return routeBuilder.Build(actions.Version);
        }