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

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

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

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

Однако то, что я ищу, кажется неуловимым. Я пытаюсь взять 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, делают это, но я просто не могу найти синтаксис для этого.

Ответы [ 2 ]

13 голосов
/ 12 сентября 2008

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

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

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

3 голосов
/ 06 мая 2016

Я разработал Второй вариант Кента Бугаарта . По сути, я должен был:

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

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

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

...