Как ActionDescriptorProviderContext получает результаты? - PullRequest
0 голосов
/ 22 апреля 2019

В Microsoft.AspNetCore.OData.Routing.Conventions.DefaultODataRoutingConvention.SelectAction (RouteContext routeContext) , мой класс контроллера не отображается в IActionDescriptorCollectionProvider requiredService = routeContext.HttpConserG.Revice.Revice.Service.Revice.Revice.Exservice.Revice.Revice.Exchange);

Моя сборка, которая содержит вышеуказанный класс, находится в той же папке bin.Это вызывает проблему «Отсутствует шаблон соответствия действий», хотя для этого есть код (класс контроллера вместе с его методом).

Я обнаружил, что проблема вызвана отсутствующим элементом (который является моимкласс контроллера) в объекте Microsoft.AspNetCore.Mvc.Infrastructure.ActionDescriptorCollection.Items , который вызывается предыдущей строкой routeContext.HttpContext.RequestServices.GetRequiredService (); .

...
      string str3 = !string.IsNullOrEmpty(str2) ? str1 + "/" + str2 : str1;
      //below is the problematic part
      IActionDescriptorCollectionProvider requiredService = routeContext.HttpContext.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>();
      List<ActionDescriptor> actionDescriptorList = new List<ActionDescriptor>();
      ActionDescriptor actionDescriptor1 = (ActionDescriptor) null;
      foreach (ControllerActionDescriptor actionDescriptor2 in requiredService.ActionDescriptors.Items.OfType<ControllerActionDescriptor>())
      {...

Поскольку свойство Items назначается в конструкторе ActionDescriptorCollection , который получает параметр IReadOnlyList items , я также попытался выяснить, как вызывается конструктор.

namespace Microsoft.AspNetCore.Mvc.Infrastructure
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;

    public class ActionDescriptorCollection
    {
        public ActionDescriptorCollection(IReadOnlyList<ActionDescriptor> items, int version)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }
            this.<Items>k__BackingField = items;
            this.<Version>k__BackingField = version;
        }

На основе трассировки стека он вызывается методом UpdateCollection () из Microsoft.AspNetCore.Mvc.Internal.ActionDescriptorCollectionProvider в строке _collection = new ActionDescriptorCollection (new ReadOnlyCollection ( context.Results ), Interlocked.Increment (ref _version));

namespace Microsoft.AspNetCore.Mvc.Internal
{
    /// <summary>
    /// Default implementation of <see cref="IActionDescriptorCollectionProvider"/>.
    /// </summary>
    public class ActionDescriptorCollectionProvider : IActionDescriptorCollectionProvider
    {
...
        private void UpdateCollection()
        {
            var context = new ActionDescriptorProviderContext();

            for (var i = 0; i < _actionDescriptorProviders.Length; i++)
            {
                _actionDescriptorProviders[i].OnProvidersExecuting(context);
            }

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

            _collection = new ActionDescriptorCollection(
                new ReadOnlyCollection<ActionDescriptor>(context.Results),
                Interlocked.Increment(ref _version));
        }
    }
}

Контекст . Результаты - это ActionDescriptorProviderContext.Results

namespace Microsoft.AspNetCore.Mvc.Abstractions
{
    public class ActionDescriptorProviderContext
    {
        public IList<ActionDescriptor> Results
        {
            [CompilerGenerated]
            get
            {
                return this.<Results>k__BackingField;
            }
        }

        public ActionDescriptorProviderContext()
        {
            this.<Results>k__BackingField = new List<ActionDescriptor>();
            base..ctor();
        }
    }
}

С этого момента, как результаты заполняются значением?Я ожидаю увидеть класс из сборки, которая находится в папке bin вместе.

...