Как предотвратить ReflectionTypeLoadException при вызове Assembly.GetTypes ()
Я пытаюсь отсканировать сборку для типов, реализующих определенный интерфейс, используя код, подобный этому:
public List FindTypesImplementing(string assemblyPath) { var matchingTypes = new List(); var asm = Assembly.LoadFrom(assemblyPath); foreach (var t in asm.GetTypes()) { if (typeof(T).IsAssignableFrom(t)) matchingTypes.Add(t); } return matchingTypes; }
Моя проблема заключается в том, что я получаю asm.GetTypes()
ReflectionTypeLoadException
при вызове asm.GetTypes()
в некоторых случаях, например, если assembly содержит типы, ссылающиеся на сборку, которая в настоящее время недоступна.
В моем случае меня не интересуют типы, которые вызывают проблему. Типы, которые я ищу, не нуждаются в недоступных assemblyх.
- Как начать работу с Jenkins после успешной работы нескольких одновременных восходящих рабочих мест?
- В мультимодульном проекте Maven, как отключить плагин у одного ребенка?
- Лучший способ расширения плагина jQuery
- java был запущен, но вернулся код выхода = -805306369
- Как написать плагин для Eclipse?
Возникает вопрос: возможно ли каким-то образом пропускать / игнорировать типы, вызывающие исключение, но все же обрабатывать другие типы, содержащиеся в сборке?
- Мне нужна firebase database браузера на стороне клиента. Каковы мои варианты
- Плагины Eclipse против функций против разломов
- Как сделать вывод CMake в директорию 'bin'?
- Просмотры в отдельных assemblyх в ASP.NET MVC
- Grails не может установить плагин
- Установка Checkstyle-Plugin (7.2.0) для Eclipse Neon не выполняется
- Как проиндексировать PDF-файл в Elasticsearch 5.0.0 с помощью плагина ingest-attachment?
- Разница между jQuery.extend и jQuery.fn.extend?
Один довольно неприятный способ:
Type[] types; try { types = asm.GetTypes(); } catch (ReflectionTypeLoadException e) { types = e.Types; } foreach (var t in types.Where(t => t != null)) { ... }
Это определенно раздражает, что нужно это делать. Вы можете использовать метод расширения, чтобы сделать его более приятным в «клиентском» коде:
public static IEnumerable GetLoadableTypes(this Assembly assembly) { // TODO: Argument validation try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException e) { return e.Types.Where(t => t != null); } }
Возможно, вы захотите перенести оператор return
из блока catch – я не очень увлечен тем, что он сам, но это, вероятно , самый короткий код …
Хотя кажется, что ничего не может быть сделано без получения ReflectionTypeLoadException в какой-то момент, ответы, приведенные выше, ограничены тем, что любая попытка использовать типы, предоставленные из исключения, по-прежнему будет иметь проблему с исходной проблемой, из-за которой тип не загружается.
Чтобы преодолеть это, следующий код ограничивает типы теми, которые расположены в сборке, и позволяет предикату дополнительно ограничивать список типов.
/// /// Get the types within the assembly that match the predicate. /// for example, to get all types within a namespace /// typeof(SomeClassInAssemblyYouWant).Assembly.GetMatchingTypesInAssembly(item => "MyNamespace".Equals(item.Namespace)) /// /// The assembly to search /// The predicate query to match against /// The collection of types within the assembly that match the predicate public static ICollection GetMatchingTypesInAssembly(this Assembly assembly, Predicate predicate) { ICollection types = new List (); try { types = assembly.GetTypes().Where(i => i != null && predicate(i) && i.Assembly == assembly).ToList(); } catch (ReflectionTypeLoadException ex) { foreach (Type theType in ex.Types) { try { if (theType != null && predicate(theType) && theType.Assembly == assembly) types.Add(theType); } // This exception list is not exhaustive, modify to suit any reasons // you find for failure to parse a single assembly catch (BadImageFormatException) { // Type not in this assembly - reference to elsewhere ignored } } } return types; }
Вы рассматривали Assembly.ReflectionOnlyLoad ? Учитывая то, что вы пытаетесь сделать, этого может быть достаточно.
В моем случае та же проблема была вызвана наличием нежелательных сборок в папке приложения. Попробуйте очистить папку Bin и перестроить приложение.