Используются ли разные контексты загрузки для сборок, на которые ссылаются, при вызове сборки .NET через COM / Interop или через приложение .NET? - PullRequest
2 голосов
/ 20 апреля 2011

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

Чтобы попытаться сделать это проще для понимания, это игроки:

  • VB6 Приложение: LegacyApp.exe
  • Сборка, содержащая информацию об интерфейсе, используемую во всех сборках .NET: MeatyInterfaces.dll
  • COM-видимая сборка .NET: InteropAssembly.dll
    • Эта сборка имеет прямую ссылку на MeatyInterfaces.dll
  • Сборка, используемая InteropAssembly.dll: MeatyImplementations.dll
    • Эта сборка имеет прямую ссылку на MeatyInterfaces.dll и реализует эти интерфейсы
    • реализует интерфейс "MeatyInterfaces.IExampleInterface" с реализацией "MeatyImplementations.ExampleImplementation"

Чтобы упростить процесс, по сути, мы создаем домен приложения и создаем экземпляр ExampleImplementation из нового домена домена как такового в коде InteropAssembly.dll, вызываемом LegacyApp.exe:

AppDomainSetup domainSetup = GetExampleSetupInfo();
AppDomain domain = AppDomain.CreateDomain(domainSetup.ApplicationName, AppDomain.CurrentDomain.Evidence, domainSetup);
ObjectHandle handle = domain.CreateInstance("MeatyImplementations.dll", "MeatyImplementations.ExampleImplementation");

Получив этот дескриптор, мы пытаемся развернуть его и привести к IExampleInterface, который реализует ExampleImplementation.

MeatyInterfaces.IExampleInterface initializer = (MeatyInterfaces.IExampleInterface) handle.Unwrap();

Это вызывает следующее исключение:

Exception: "System.InvalidCastException"
Message: "Unable to cast transparent proxy to type 'MeatyInterfaces.IExampleInterface'"

Странно то, что если мы выполним этот точный код, но начнем с управляемого приложения (.NET), оно будет отлично работать.

Вот что я знаю:

  • Я знаю, что есть два контекста, в которых можно загружать сборки: Load и LoadFrom, и что последний чувствителен к расположению DLL.
  • Я знаю, что приведение объекта из одного загрузочного контекста в другой, кажется, является наиболее частой причиной этой проблемы (фактически, единственной, которую я смог найти довольно исчерпывающим поиском)
  • Я знаю, что, если я переопределю событие AssemblyResolve, как рекомендовано здесь (http://west -wind.com / weblog / posts / 601200.aspx ), это устранит проблему, которая далее мне подсказывает (хотя у меня нет вещественных доказательств), что InteropAssembly.dll должен загружать MeatyInterfaces.dll в другом контексте загрузки, чем MeatyImplementations.dll, когда используется способом, показанным выше.

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

Чего я не понимаю, так это того, почему контекст загрузки будет отличаться в зависимости от того, использую ли я InteropAssembly.dll через приложение VB6 (с помощью COM Interop), а не приложение .NET, или от концепции полной загрузки. Все это время контексты были просто красной сельдью, и его решение лишь случайно решило мою проблему.

1 Ответ

0 голосов
/ 20 апреля 2011

Я нашел ответ:

Я неправильно смотрел журнал Fusion:

InteropAssembly.dll загружался в контексте LoadFrom, но это не было проблемой.Проблема заключалась в том, что, когда InteropAssembly.dll пытался загрузить MeatyInterfaces.dll, он не мог найти его: MeatyInterfaces.dll находился в папке bin, где находился InteropAssembly.dll, но не искал его: он искалв пути приложения LegacyApp.exe.

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

Исключение, которое я видел, которое привело меня к пути контекста загрузки, было в основном совпадением: сбой загрузки зависимости не вызывал исключение до тех пор, пока оно не появилось в первый раз.используется, что произошло именно там, где произошло приведение: которое вызвало исключение, которое, по-видимому, было вызвано несоответствующими контекстами нагрузки в подавляющем большинстве случаев.

F7U12

Да, так что это былопричина: теперь я усвоил трудный путь, что хотя сборка может быть загружена через COMВзаимодействуя с местоположением, отличным от пути вызывающего приложения (или GAC), зависимости сборки все равно должны находиться в пути приложения.D'о.

...