С# Reflection: Получить * все * активные сборки в решении?
Вот моя проблема:
У меня есть 2 проекта - один "общий" проект с такими действиями, как библиотека со всеми видами кода поддержки и фактическая программа, которая использует указанный проект во многих своих вызовах. Мы будем называть эти проекты "Common" и "Program". Они оба находятся в одном и том же решении.
Внутри "Common" у меня есть класс для задач комбо-размышления, например создание экземпляра. Если я вызываю GetExecutingAssembly, он получает все "общие" типы, однако, когда я использую GetEntryAssembly, я получаю типы "Program".
Хотя я, конечно, мог редактировать код для работы с двумя наборами asm, я боюсь ситуации, когда в решении есть не более двух проектов - скажем 5 (не знаю почему, но позволяет просто пойдите туда сейчас), и я боюсь, что вызов GetExecutingAssembly и GetEntryAssembly не получит все типы во всей программе.
Есть ли что-то еще, что я могу сделать, чтобы получить все типы в решении?
Ответы
Ответ 1
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Это приведет к загрузке всех загруженных сборок в текущем AppDomain.
Как отмечено в комментариях, возможно порождать несколько AppDomains, и в этом случае каждый может иметь свои собственные сборки. Непосредственным преимуществом этого является то, что вы можете разгружать сборки, выгружая содержащий AppDomain.
Ответ 2
Это действительно старый вопрос, но для дальнейшего использования здесь полная реализация:
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);
}
Ответ 3
Как насчет 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. Это только один уровень глубины в цепочке ref.. но может быть рекурсивно - с большим количеством кода.
Ответ 4
Также: некоторые сборки не загружаются сразу, поэтому вы также должны поместить обработчик событий в событие загрузки сборки AppDomain.
AppDomain.CurrentDomain.AssemblyLoad += ....