मैं इसकी सराहना करता हूं यह एक बहुत पुराना सवाल है, लेकिन मुझे लगा कि मैं भविष्य के उपयोगकर्ताओं के लिए एक और उत्तर जोड़ूंगा क्योंकि सभी उत्तर किसी न किसी रूप का उपयोग करते हैं Assembly.GetTypes
।
Whilst GetTypes () वास्तव में सभी प्रकारों को वापस करेगा, इसका मतलब यह नहीं है कि आप उन्हें सक्रिय कर सकते हैं और इस प्रकार संभवतः फेंक सकते हैं ReflectionTypeLoadException
।
एक प्रकार को सक्रिय नहीं करने के लिए एक क्लासिक उदाहरण तब होगा जब प्रकार लौटाया गया derived
हो, base
लेकिन base
उस विधानसभा से अलग विधानसभा में परिभाषित किया गया हो derived
, जिसे कॉलिंग असेंबली संदर्भित नहीं करती है।
तो हम कहते हैं:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
में तो ClassC
है, जिसमें है AssemblyC
हम तो स्वीकार किए जाते हैं जवाब के अनुसार कुछ करना:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
तो यह एक फेंक देंगे ReflectionTypeLoadException
।
इसका कारण यह है के लिए एक संदर्भ के बिना है AssemblyA
में AssemblyC
आप के लिए सक्षम नहीं होगा:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
दूसरे शब्दों ClassB
में, लोड करने योग्य नहीं है जो कुछ ऐसा है जो गेटटाइप्स कॉल को चेक करता है और फेंकता है।
तो लोड करने योग्य प्रकारों के लिए निर्धारित परिणाम को सुरक्षित रूप से अर्हता प्राप्त करने के लिए इस फिल हैकेड लेख के अनुसार एक विधानसभा और जॉन स्कीट कोड में सभी प्रकार प्राप्त करें, इसके बजाय आप कुछ ऐसा करेंगे:
public static class TypeLoaderExtensions {
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) {
if (assembly == null) throw new ArgumentNullException("assembly");
try {
return assembly.GetTypes();
} catch (ReflectionTypeLoadException e) {
return e.Types.Where(t => t != null);
}
}
}
और तब:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}