解决方法
您可以使用反射枚举程序集中的所有类,并仅过滤继承自Controller类的类.
最好的参考是asp.net mvc source code.看看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; }