我使用COM Interop從VB6應用程序調用託管代碼,該應用程序本身在創建新AppDomain後隨後調用另一個託管程序集中的代碼。這個新的AppDomain是實際實例化正在使用的對象的實例。當通過COM/Interop或.NET應用程序調用.NET程序集時,是否有不同的加載上下文用於引用的程序集?
開始嘗試做這個容易理解,這些都是玩家:
- VB6應用: LegacyApp.exe在所有.NET組件中使用
- 大會包含的接口信息: MeatyInterfaces。 dll
- COM Interop-visible .NET程序集: InteropAssembly.dll
- 此組件具有直接引用MeatyInterfaces.dll
- 大會通過InteropAssembly.dll使用: MeatyImplementations.dll
- 此組件具有直接引用MeatyInterfaces.dll,並實現這些接口
- 實現接口 「MeatyInterfaces.IExampleInterface」 與實施 「MeatyImplementations.ExampleImplementation」
歸結過程中,基本上是我們創建一個AppDomain並實例在新的AppDomain中ExampleImplementation這樣由LegacyApp.exe稱爲InteropAssembly.dll代碼:
AppDomainSetup domainSetup = GetExampleSetupInfo();
AppDomain domain = AppDomain.CreateDomain(domainSetup.ApplicationName, AppDomain.CurrentDomain.Evidence, domainSetup);
ObjectHandle handle = domain.CreateInstance("MeatyImplementations.dll", "MeatyImplementations.ExampleImplementation");
一旦我們有了這個句柄,我們試圖將其解包並將其轉換爲ExampleImplementation實現的IExampleInterface。
MeatyInterfaces.IExampleInterface initializer = (MeatyInterfaces.IExampleInterface) handle.Unwrap();
這將引發以下異常:
Exception: "System.InvalidCastException"
Message: "Unable to cast transparent proxy to type 'MeatyInterfaces.IExampleInterface'"
奇怪的是,如果我們通過這個確切的代碼運行,但託管(.NET)應用程序開始,它完美的罰款。
這是我知道的:
- 我知道有兩種背景組件可以被加載:加載並LoadFrom,而後者是dll的位置敏感。
- 我知道將一個對象從一個Load Context轉換到另一個Load Context似乎是這個問題的最常見原因(實際上,我只能找到一個相當詳盡的搜索)
- 我知道,如果我按照這裏推薦的方法(http://west-wind.com/weblog/posts/601200.aspx)重寫AssemblyResolve事件,它會修復問題,這進一步向我暗示(儘管我沒有任何物質證據)InteropAssembly.dll必須在與MeatyImplementations.dll不同的加載上下文中加載MeatyInterfaces.dll按照上面所示的方式使用。
因此,這裏是什麼,我不明白......如果有人能提供澄清,我將不勝感激:
我不明白的是爲什麼負載情況下將取決於如果不同我通過VB6應用程序(使用COM Interop)與.NET應用程序使用InteropAssembly.dll,或者Load Contexts的整個概念一直是一個紅鯡魚,他的修復只是巧合解決了我的問題。