Найти типы во всех сборках - PullRequest
56 голосов
/ 14 января 2011

Мне нужно искать конкретные типы во всех сборках на веб-сайте или в приложении Windows. Есть ли простой способ сделать это?Например, как фабрика контроллеров для ASP.NET MVC просматривает все сборки для контроллеров.

Спасибо.

Ответы [ 4 ]

94 голосов
/ 14 января 2011

Для этого есть два шага:

  • AppDomain.CurrentDomain.GetAssemblies() предоставляет вам все сборки, загруженные в текущем домене приложения.
  • Класс Assembly предоставляет метод GetTypes() для извлечения всех типов в этой конкретной сборке.

Следовательно, ваш код может выглядеть так:

foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
    foreach (Type t in a.GetTypes())
    {
        // ... do something with 't' ...
    }
}

Чтобы искать конкретные типы (например, реализовать определенный интерфейс, наследовать от общего предка или что-то еще), вам придется отфильтровать результаты. В случае, если вам нужно сделать это в нескольких местах приложения, рекомендуется создать вспомогательный класс с различными параметрами. Например, я обычно применяю фильтры префиксов пространства имен, фильтры реализации интерфейса и фильтры наследования.

Для получения подробной документации посмотрите MSDN здесь и здесь .

29 голосов
/ 15 января 2011

Легко с помощью Linq:

IEnumerable<Type> types =
            from a in AppDomain.CurrentDomain.GetAssemblies()
            from t in a.GetTypes()
            select t;

foreach(Type t in types)
{
    ...
}
27 голосов
/ 31 декабря 2013

Решение 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));
}
5 голосов
/ 04 марта 2016

Чаще всего вас интересуют только сборки, которые видны снаружи.Для этого вам нужно вызвать GetExportedTypes () , но кроме этого может быть выдано 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;
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...