Поиск типов во всех сборках
Мне нужно искать определенные типы во всех сборках на веб-сайте или в приложении windows, есть ли простой способ сделать это? Как как фабрика регулятора для ASP.NET MVC просматривает все сборки для контроллеров.
спасибо.
4 ответа:
есть два шага для достижения этой цели:
- The
AppDomain.CurrentDomain.GetAssemblies()
дает вам все сборки, загруженные в текущем домене приложения.- The
Assembly
класс обеспечиваетGetTypes()
метод для извлечения всех типов в этой конкретной сборки.следовательно, ваш код может выглядеть так:
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type t in a.GetTypes()) { // ... do something with 't' ... } }
для поиска конкретных типов (например, реализация данного интерфейса, наследование от общего предка или что-то еще) вам придется отфильтровать результат. В случае, если вам нужно сделать это в нескольких местах в вашем приложении, это хорошая идея, чтобы создать вспомогательный класс, предоставляющий разные варианты. Например, я обычно применял фильтры префикса пространства имен, фильтры реализации интерфейса и фильтры наследования.
для получения подробной документации загляните в MSDN здесь и здесь.
простота использования Linq:
IEnumerable<Type> types = from a in AppDomain.CurrentDomain.GetAssemblies() from t in a.GetTypes() select t; foreach(Type t in types) { ... }
решение LINQ с проверкой, является ли сборка динамической:
/// <summary> /// Looks in all loaded assemblies for the given type. /// </summary> /// <param name="fullName"> /// The full name of the type. /// </param> /// <returns> /// The <see cref="Type"/> found; null if not found. /// </returns> private static Type FindType(string fullName) { return AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.IsDynamic) .SelectMany(a => a.GetTypes()) .FirstOrDefault(t => t.FullName.Equals(fullName)); }
чаще всего вас интересуют только сборки, которые видны снаружи. Для этого вам нужно позвонить GetExportedTypes() но кроме этого a ReflectionTypeLoadException может быть брошен. В следующем коде рассматриваются эти ситуации.
public static IEnumerable<Type> FindTypes(Func<Type, bool> predicate) { if (predicate == null) throw new ArgumentNullException(nameof(predicate)); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!assembly.IsDynamic) { Type[] exportedTypes = null; try { exportedTypes = assembly.GetExportedTypes(); } catch (ReflectionTypeLoadException e) { exportedTypes = e.Types; } if (exportedTypes != null) { foreach (var type in exportedTypes) { if (predicate(type)) yield return type; } } } } }