ASP.NET MVC: Получите все контроллеры

Действительно ли возможно получить все контроллеры, доступные ControllerFactory?
То, что я хочу сделать, получают список всех типов контроллера в приложении, но последовательным способом.

Так, чтобы все контроллеры, которые я получаю, были тем же разрешением запроса значения по умолчанию, использует.

(Фактическая задача состоит в том, чтобы найти все методы действия, которые имеют данный атрибут).

14
задан Andrey Shchekin 10 December 2009 в 11:30
поделиться

2 ответа

Вы можете использовать отражение для перечисления всех классов в сборке и фильтрации только классов, наследуемых от класса Controller.

Лучшая ссылка - исходный код asp.net mvc . Взгляните на реализации классов ControllerTypeCache и ActionMethodSelector . ControllerTypeCache показывает, как получить доступ ко всем классам контроллеров.

       internal static bool IsControllerType(Type t) {
            return
                t != null &&
                t.IsPublic &&
                t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
                !t.IsAbstract &&
                typeof(IController).IsAssignableFrom(t);
        }

 public void EnsureInitialized(IBuildManager buildManager) {
            if (_cache == null) {
                lock (_lockObj) {
                    if (_cache == null) {
                        List<Type> controllerTypes = GetAllControllerTypes(buildManager);
                        var groupedByName = controllerTypes.GroupBy(
                            t => t.Name.Substring(0, t.Name.Length - "Controller".Length),
                            StringComparer.OrdinalIgnoreCase);
                        _cache = groupedByName.ToDictionary(
                            g => g.Key,
                            g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase),
                            StringComparer.OrdinalIgnoreCase);
                    }
                }
            }
        }

А ActionMethodSelector показывает, как проверить, имеет ли метод желаемый атрибут.

private static List<MethodInfo> RunSelectionFilters(ControllerContext controllerContext, List<MethodInfo> methodInfos) {
            // remove all methods which are opting out of this request
            // to opt out, at least one attribute defined on the method must return false

            List<MethodInfo> matchesWithSelectionAttributes = new List<MethodInfo>();
            List<MethodInfo> matchesWithoutSelectionAttributes = new List<MethodInfo>();

            foreach (MethodInfo methodInfo in methodInfos) {
                ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */);
                if (attrs.Length == 0) {
                    matchesWithoutSelectionAttributes.Add(methodInfo);
                }
                else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) {
                    matchesWithSelectionAttributes.Add(methodInfo);
                }
            }

            // if a matching action method had a selection attribute, consider it more specific than a matching action method
            // without a selection attribute
            return (matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes;
        }
12
ответ дан 1 December 2019 в 13:21
поделиться

Я не думаю, что можно дать простой ответ на этот вопрос, потому что это зависит от множества разных вещей, включая реализацию IControllerFactory.

Например, если у вас есть полностью настроенная на заказ реализация IControllerFactory, все ставки отключены, потому что она может использовать любой вид механизм для создания экземпляров контроллера.

Однако DefaultControllerFactory отслеживает соответствующий тип контроллера во всех сборках, определенных в RouteCollection (настроенных в global.asax).

7
ответ дан 1 December 2019 в 13:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: