2009-12-10 18 views
14

क्या नियंत्रक फैक्टरी में सभी नियंत्रक उपलब्ध हो सकते हैं?
मैं क्या करना चाहता हूं एप्लिकेशन में सभी नियंत्रक प्रकारों की एक सूची प्राप्त करें, लेकिन एक निरंतर तरीके से।एएसपी.नेट एमवीसी: सभी नियंत्रक प्राप्त करें

ताकि मेरे द्वारा प्राप्त सभी नियंत्रक एक ही डिफ़ॉल्ट अनुरोध समाधान का उपयोग कर रहे हों।

(वास्तविक कार्य उन सभी क्रिया विधियों को ढूंढना है जिनमें दिए गए गुण हैं)।

उत्तर

12

आप एक असेंबली में सभी वर्गों की गणना करने के लिए प्रतिबिंब का उपयोग कर सकते हैं, और केवल कक्षाओं को नियंत्रक वर्ग से प्राप्त करने के लिए फ़िल्टर कर सकते हैं।

सर्वोत्तम संदर्भ asp.net mvc source code है। ControllerTypeCache और ActionMethodSelector कक्षा के कार्यान्वयन का एक नज़र डालें। नियंत्रक टाइपकाक दिखाता है कि सभी नियंत्रक कक्षाएं कैसे उपलब्ध कराएं।

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

आंतरिक, मेरी इच्छा है कि उन्होंने ऐसा नहीं किया। लेकिन ठीक है, यह जवाब है। –

7

मैं इसे, इस सवाल का एक सरल जवाब देने के लिए संभव है, क्योंकि यह IControllerFactory के कार्यान्वयन सहित अलग अलग बातें, का एक बहुत पर निर्भर करता है नहीं लगता।

उदाहरण के लिए, यदि आपके पास पूरी तरह से कस्टम-निर्मित आईसींट्रोलर फैक्ट्री कार्यान्वयन है, तो सभी दांव बंद हैं, क्योंकि यह नियंत्रक उदाहरण बनाने के लिए किसी भी तंत्र का उपयोग कर सकता है।

हालांकि, DefaultControllerFactory रूटकोलेक्शन (global.asax में कॉन्फ़िगर) में परिभाषित सभी असेंबली में उपयुक्त नियंत्रक प्रकार की देखभाल करता है।

इस मामले में, आप रूट कोलेक्शन से जुड़े सभी असेंबली के माध्यम से पाश कर सकते हैं, और प्रत्येक में नियंत्रकों की तलाश कर सकते हैं। किसी दिए गए विधानसभा में

ढूँढना नियंत्रकों अपेक्षाकृत आसान है:

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

जहां asm एक सभा उदाहरण है।

संबंधित मुद्दे