Общий контроллер не регистрируется - PullRequest
0 голосов
/ 04 апреля 2019

Сгенерировал допустимые типы для всех моих универсальных контроллеров и вызывает метод PopulateFeature в параметрах ConfigureApplicationPartManager, но когда я пытаюсь реализовать GenericControllerRouteConvention, контроллер отсутствует в списке зарегистрированных контроллеров.

  var providerTypes = new List<Type>();
            var refAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Select(Assembly.Load);
            foreach (var assembly in refAssemblies)
            {
                var candidates = assembly.GetExportedTypes().Where( x => 
                    x.IsClass && 
                    !x.IsAbstract  && 
                    x.BaseType.IsGenericType && 
                    x.BaseType.GetGenericTypeDefinition() == typeof(DataProvider<,>));

                foreach (var candidate in candidates)
                {
                    providerTypes.Add(candidate);
                }
            }

            services.
                AddMvc(c =>
                    c.Conventions.Add(
                        new GenericControllerRouteConvention()
                )).
                ConfigureApplicationPartManager(o => 
                {
                    var contollerFeature = new ControllerFeature();

                    foreach (var providerType in providerTypes)
                    {
                        contollerFeature.Controllers.Add(
                                typeof(DataProviderContoller<,,>)
                                .MakeGenericType(
                                    providerType, 
                                    providerType.BaseType.GetGenericArguments()[0], 
                                    providerType.BaseType.GetGenericArguments()[1])
                                .GetTypeInfo());
                    }  

                    o.PopulateFeature(contollerFeature);                                       
                });

Универсальный контроллер


 public class DataProviderContoller<TProvider, TModel, TKey> : Controller
        where TProvider : DataProvider<TModel, TKey> 
    {
        private readonly DataProvider<TModel, TKey> _dataProvider;

        public DataProviderContoller(TProvider dataProvider)
        {
            _dataProvider = dataProvider ?? throw new ArgumentNullException(nameof(dataProvider));
        }        

    }

1 Ответ

1 голос
/ 08 апреля 2019

решаемые

Добавление логики непосредственно в начальный класс было причиной моей проблемы. В другой точке жизненного цикла запуска приложения функция заполнения для функции контроллера будет переопределена. Мне пришлось создать класс, унаследованный от поставщика функций приложения I:

GenericControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>

Зарегистрируйте его в классе запуска

 services.AddMvc(c =>
                c.Conventions.Add(new GenericControllerRouteConvention()
            ))
            .ConfigureApplicationPartManager(apm =>
            {
                apm.FeatureProviders.Add(new GenericControllerFeatureProvider(GetDataProviders()));
            });
...