C # Reflection: Получить * все * активные сборки в решении? - PullRequest
21 голосов
/ 12 мая 2009

Вот моя проблема:

У меня есть 2 проекта - один «общий» проект, действующий как библиотека со всеми видами вспомогательного кода, и программа, которая использует указанный проект во многих своих вызовах. Мы будем называть эти проекты "Общие" и "Программа". Они оба в одном решении.

В «Общем» у меня есть класс для заданий на отражение, например, создание экземпляра. Если я вызываю GetExecutingAssembly, он получает все «общие» типы, однако, когда я использую GetEntryAssembly, я получаю типы «Program».

Хотя я, конечно, мог бы отредактировать код для работы с 2 наборами asm, я боюсь ситуации, когда в решении будет более двух проектов - скажем, 5 (не знаю почему, но давайте просто пока что), и я боюсь, что вызов GetExecutingAssembly и GetEntryAssembly не получит все типы во всей программе.

Есть ли что-то еще, что я могу сделать, чтобы получить все типы в решении ?

Ответы [ 4 ]

58 голосов
/ 12 мая 2009
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

Получит все загруженные сборки в текущем домене приложений.

Как отмечено в комментариях, возможно порождение нескольких доменов приложений, в этом случае каждый может иметь свои собственные сборки. Непосредственным преимуществом этого является то, что вы можете выгружать сборки, выгружая содержащий домен приложения.

35 голосов
/ 21 апреля 2012

Это действительно старый вопрос, но для дальнейшего использования здесь приведена полная реализация:

    public static IEnumerable<Assembly> GetAssemblies()
    {
        var list = new List<string>();
        var stack = new Stack<Assembly>();

        stack.Push(Assembly.GetEntryAssembly());

        do
        {
            var asm = stack.Pop();

            yield return asm;

            foreach (var reference in asm.GetReferencedAssemblies())
                if (!list.Contains(reference.FullName))
                {
                    stack.Push(Assembly.Load(reference));
                    list.Add(reference.FullName);
                }

        }
        while (stack.Count > 0);

    }
9 голосов
/ 12 мая 2009

Также: некоторые сборки загружаются не сразу, поэтому вы должны также добавить обработчик событий в событие загрузки сборки домена приложения.

AppDomain.CurrentDomain.AssemblyLoad += ....
8 голосов
/ 12 мая 2009

Как насчет GetReferencedAssemblies для обработки записей метаданных AssemblyRef? «Решение» - это не то, что CLR знает или волнует… оно имеет дело с Ассамблеями.

private static List<Assembly> GetListOfEntryAssemblyWithReferences()
{
  List<Assembly> listOfAssemblies = new List<Assembly>();
  var mainAsm = Assembly.GetEntryAssembly();
  listOfAssemblies.Add(mainAsm);

  foreach (var refAsmName in mainAsm.GetReferencedAssemblies())
  {
    listOfAssemblies.Add(Assembly.Load(refAsmName));
  }
  return listOfAssemblies;
}

Предостережения:
1. Вам все равно нужно отфильтровать основные сборки системы. * 2. Это просто на один уровень в цепочке ссылок ... но может быть сделано рекурсивно - с большим количеством кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...