public void OnProvidersExecuting(ActionDescriptorProviderContext context)
        {
            var newContext = new ActionDescriptorProviderContext();

            _pageActionDescriptorProvider.OnProvidersExecuting(newContext);
            _pageActionDescriptorProvider.OnProvidersExecuted(newContext);

            var feature = new ViewsFeature();

            _applicationPartManager.PopulateFeature(feature);

            var lookup = new Dictionary <string, CompiledViewDescriptor>(feature.ViewDescriptors.Count, StringComparer.Ordinal);

            foreach (var viewDescriptor in feature.ViewDescriptors)
            {
                // View ordering has precedence semantics, a view with a higher precedence was not
                // already added to the list.
                lookup.TryAdd(ViewPath.NormalizePath(viewDescriptor.RelativePath), viewDescriptor);
            }

            foreach (var item in newContext.Results)
            {
                var pageActionDescriptor = (PageActionDescriptor)item;
                if (!lookup.TryGetValue(pageActionDescriptor.RelativePath, out var compiledViewDescriptor))
                {
                    throw new InvalidOperationException($"A descriptor for '{pageActionDescriptor.RelativePath}' was not found.");
                }

                var compiledPageActionDescriptor = _compiledPageActionDescriptorFactory.CreateCompiledDescriptor(
                    pageActionDescriptor,
                    compiledViewDescriptor);
                context.Results.Add(compiledPageActionDescriptor);
            }
        }
Пример #2
0
        private async Task <CompiledPageActionDescriptor> LoadAsyncCore(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata)
        {
            var viewDescriptor = await Compiler.CompileAsync(actionDescriptor.RelativePath);

            var compiled = _compiledPageActionDescriptorFactory.CreateCompiledDescriptor(actionDescriptor, viewDescriptor);

            var endpoints = new List <Endpoint>();

            _endpointFactory.AddEndpoints(
                endpoints,
                routeNames: new HashSet <string>(StringComparer.OrdinalIgnoreCase),
                action: compiled,
                routes: Array.Empty <ConventionalRouteEntry>(),
                conventions: new Action <EndpointBuilder>[]
            {
                b =>
                {
                    // Copy Endpoint metadata for PageActionActionDescriptor to the compiled one.
                    // This is particularly important for the runtime compiled scenario where endpoint metadata is added
                    // to the PageActionDescriptor, which needs to be accounted for when constructing the
                    // CompiledPageActionDescriptor as part of the one of the many matcher policies.
                    // Metadata from PageActionDescriptor is less significant than the one discovered from the compiled type.
                    // Consequently, we'll insert it at the beginning.
                    for (var i = endpointMetadata.Count - 1; i >= 0; i--)
                    {
                        b.Metadata.Insert(0, endpointMetadata[i]);
                    }
                },
            },
                createInertEndpoints: false);

            // In some test scenarios there's no route so the endpoint isn't created. This is fine because
            // it won't happen for real.
            compiled.Endpoint = endpoints.SingleOrDefault();

            return(compiled);
        }