Bunun çok eski bir soru olduğunu takdir ediyorum ama bugüne kadarki tüm cevaplar bir tür kullandığından gelecekteki kullanıcılar için başka bir cevap ekleyeceğimi düşündüm Assembly.GetTypes.
GetTypes () gerçekten tüm türleri döndürecek olsa da, onları etkinleştirebileceğiniz ve dolayısıyla potansiyel olarak a atabileceğiniz anlamına gelmez ReflectionTypeLoadException.
Bir türü etkinleştirememenin klasik bir örneği, döndürülen türün , çağrı derlemesinin başvuruda bulunmadığı bir derlemeden farklı olduğu derived, baseancak bu türden basefarklı bir derlemede tanımlandığı durumdur derived.
Diyelim ki elimizde:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
İçinde ClassCise, AssemblyCkabul edilen cevaba göre bir şey yaparız:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
Sonra a atacak ReflectionTypeLoadException.
Bunun nedeni için bir referans olmadan AssemblyA içinde AssemblyCsize mümkün olmaz:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
Başka bir deyişle ClassBdeğil yüklenebilir GetTypes çek çağrısı ve üzerinde atar şeydir.
Yüklenebilir türler için sonuç kümesini güvenli bir şekilde nitelendirmek için, bu Phil Haacked makalesine göre Bir Montajdaki Tüm Türleri Al ve Jon Skeet koduna göre şöyle bir şey yaparsınız:
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);
}
}
}
Ve sonra:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}