Question

Est-il possible d'obtenir tous les contrôleurs disponibles à un ControllerFactory
Ce que je veux faire est d'obtenir une liste de tous les types de contrôleur dans l'application, mais d'une manière cohérente.

Alors que tous les contrôleurs que je reçois sont les mêmes que ceux de la résolution demande par défaut utilise.

(La tâche réelle est de trouver toutes les méthodes d'action qui ont un attribut donné).

Était-ce utile?

La solution

Vous pouvez utiliser la réflexion pour énumérer toutes les classes dans un ensemble, et filtrer uniquement les classes héritent de la classe Controller.

La meilleure référence est asp.net code source mvc. Jetez un oeil des implémentations de ControllerTypeCache et ActionMethodSelector classe . ControllerTypeCache montre comment obtenir toutes les classes de contrôleur disponibles.

       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);
                    }
                }
            }
        }

Et ActionMethodSelector montre comment vérifier si une méthode a attribut souhaité.

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;
        }

Autres conseils

Je ne pense pas qu'il soit possible de donner une réponse simple à cette question, parce que cela dépend de beaucoup de choses différentes, y compris la mise en œuvre de IControllerFactory.

Par exemple, si vous avez une implémentation IControllerFactory complètement sur mesure, tous les paris sont ouverts, car il peut utiliser une sorte de mécanisme pour créer des instances de contrôleur.

Cependant, le DefaultControllerFactory regarde après le type de contrôleur approprié dans tous les ensembles définis dans le RouteCollection (configuré dans Global.asax).

Dans ce cas, vous en boucle pourrait par tous les ensembles associés à la RouteCollection et rechercher les contrôleurs dans chaque.

Trouver des contrôleurs dans un assemblage donné est relativement facile:

var controllerTypes = from t in asm.GetExportedTypes()
                      where typeof(IController).IsAssignableFrom(t)
                      select t;

asm est une instance de l'Assemblée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top