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