无法将透明代理转换为从AppDomain输入

时间:2010-09-07 03:07:20

标签: c# .net remoting appdomain

我正在尝试在appdomain中创建一个对象:

var type = typeof (CompiledTemplate);
var obj = (CompiledTemplate) domain.CreateInstanceAndUnwrap (
    type.Assembly.FullName, type.FullName);

但是,我总是收到以下错误:

无法转换透明代理以输入'Mono.TextTemplating.CompiledTemplate'。

我在.NET 4.0上运行,而不是Mono,尽管命名空间可能会提示:)

据我所知,当.NET认为Type&程序集在两个域中不完全匹配。但是,在调试时,FullName和Location是相同的。只有Assembly.Codebase属性不同 - 在子AppDomain中,由于某种原因,它的扩展名大写为“DLL”。

我已经尝试将AssemblyResolve处理程序添加到AppDomain,它使用Assembly.LoadFrom显式加载文件名,但CodeBase的扩展仍然是大写的。由于原始程序集也加载了Assembly.LoadFrom(通过Mono.Addins),CodeBase值之间的差异似乎很奇怪。

有关修复或解决此问题的任何建议吗?

4 个答案:

答案 0 :(得分:5)

您是否遇到了程序集加载上下文的问题? (例如,见here) 你有一个明显在加载上下文中的类型(因为你正在使用typeof(CompiledTemplate)),但你说的是辅助AD中的类型被加载到加载来自上下文...

您是否检查了fuslogvw以确定正在加载哪些装配? fuslog跟踪还将告诉您程序集是否正在加载到不同的上下文中。

答案 1 :(得分:1)

组件的第二个副本实际上是按原样加载到内存中。

运行时中类型的实例特定于加载的程序集的实例 - 因此即使第二次加载相同的DLL文件,也不会认为这些类型匹配。

当“DLLHell”扩展到“GACAndDLLHell”时,这是一个典型问题。 “GACONLYHeaven”是一个更好的地方...... :)。

文件名略有不同(.DLL扩展名有不同的情况)意味着从两个地方加载相同的DLL(即:GAC不区分大小写/文件名IIRC总是小写)。 / p>

这里需要一个抽象类,或者最好是一个接口。

如果您无法对代码库进行更改,请首先确保DLL仅存在于驱动器上的1个位置(如果从GAC加载,则位于驱动器上的0个位置)。在app / bin文件夹中包含类型:'CompiledTemplate'的DLL的副本将是真正的罪魁祸首......?

这个新代码或现有代码现在因某种原因失败了吗?

答案 2 :(得分:0)

也许您可以使用dynamic关键字,而不是将其转换为特定类型:

var type = typeof (CompiledTemplate);
dynamic obj = domain.CreateInstanceAndUnwrap (
    type.Assembly.FullName, type.FullName);

这至少可以帮助您解决问题。当然,潜在的缺点是没有编译时检查和/或性能降低。但是,根据您的情况,这些可能是微不足道的权衡。

答案 3 :(得分:0)

我有一个使用回调(双工)体系结构的WCF网络命名管道应用程序。

我收到此错误是因为服务接口的[ServiceContract]被错误的回调注释了。