Как загрузить сборку и все ее зависимости во время выполнения в C# для отражения?

StackOverflow https://stackoverflow.com/questions/59220

  •  09-06-2019
  •  | 
  •  

Вопрос

Я пишу утилиту для себя, отчасти в качестве упражнения по изучению C# Reflection, а отчасти потому, что мне действительно нужен полученный инструмент для собственного использования.

Что мне нужно, так это указать приложению сборку и выбрать заданный класс, из которого можно выбрать свойства, которые должны быть включены в экспортированную HTML-форму в качестве полей.Эта форма затем будет использоваться в моем приложении ASP.NET MVC в качестве начала представления.

Поскольку я использую объекты Subsonic для приложений, которые хочу использовать, это должно быть разумно, и я решил, что, поскольку я хочу включить такие вещи, как различный выходной HTML в зависимости от типа данных, отражение было способом сделать это.

Однако то, что я ищу, кажется неуловимым.Я пытаюсь использовать DLL/EXE, выбранную через OpenFileDialog, в качестве отправной точки и загрузить ее:

String FilePath = Path.GetDirectoryName(FileName);
System.Reflection.Assembly o = System.Reflection.Assembly.LoadFile(FileName);

Это работает нормально, но поскольку объекты, созданные Subsonic, на самом деле полны типов объектов, определенных в Subsonic.dll и т. д., эти зависимые объекты не загружаются.Входить:

AssemblyName[] ReferencedAssemblies = o.GetReferencedAssemblies();

Это тоже содержит именно то, чего я ожидал.Однако я пытаюсь понять, как загрузить эти сборки, чтобы копание в моих объектах работало правильно.Я понимаю, что если бы эти сборки находились в GAC или в каталоге запущенного исполняемого файла, я мог бы просто загрузить их по их имени, но это вряд ли относится к этому варианту использования, и это мой основной вариант использования.

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

Я знаю, что такие инструменты, как Reflector, делают это, но я просто не могу найти синтаксис для этого.

Это было полезно?

Решение

Пара вариантов здесь:

  1. Прикрепить к AppDomain.AssemblyResolve и сделай еще один LoadFile на основе запрошенной сборки.
  2. Раскрути еще один AppDomain с каталогом в качестве базы и загрузите сборки в него AppDomain.

Я настоятельно рекомендую использовать вариант 2, так как он, скорее всего, будет чище и позволит вам после этого выгрузить все эти сборки.Кроме того, рассмотрите возможность загрузки сборок в контексте только для отражения, если вам нужно только размышлять над ними (см. Assembly.ReflectionOnlyLoad).

Другие советы

я работал Кент Бугартвторой вариант.По сути мне пришлось:

1.) Реализуйте ResolveEventHandler в отдельный класс, наследующий от MarshalByRefObject и добавление Serializable атрибут.

2.) Добавьте текущий ApplicationBase, по сути, там, где находится dll обработчика событий, в AppDomain PrivateBinPath.

Вы можете найти код на github.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top