Saya menghargai ini adalah pertanyaan yang sangat lama tapi saya pikir saya akan menambahkan jawaban lain untuk pengguna di masa depan karena semua jawaban sampai saat ini menggunakan beberapa bentuk Assembly.GetTypes.
Sementara GetTypes () memang akan mengembalikan semua jenis, itu tidak berarti Anda bisa mengaktifkannya dan dengan demikian berpotensi membuang a ReflectionTypeLoadException.
Contoh klasik untuk tidak dapat mengaktifkan suatu tipe adalah ketika tipe yang dikembalikan adalah deriveddari basetetapi basedidefinisikan dalam rakitan yang berbeda dari derived, rakitan yang tidak dirujuk oleh rakitan pemanggil.
Jadi katakan kita memiliki:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
Jika di ClassCdalamnya ada AssemblyCmaka kita melakukan sesuatu sesuai jawaban yang diterima:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
Maka itu akan melempar ReflectionTypeLoadException.
Ini karena tanpa referensi ke AssemblyA dalam AssemblyCAnda tidak akan dapat:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
Dengan kata lain ClassBtidak dapat dimuat yang merupakan sesuatu yang dipanggil dan dilemparkan oleh panggilan untuk GetTypes.
Jadi untuk memenuhi syarat dengan aman hasil yang ditetapkan untuk jenis yang dapat di-load maka sesuai dengan artikel Phil Haacked ini Dapatkan Semua Jenis dalam Majelis dan kode Jon Skeet Anda malah akan melakukan sesuatu seperti:
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);
}
}
}
Lalu:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}