无法将透明代理强制转换为来自 AppDomain 的类型

发布于 2024-09-18 04:13:07 字数 704 浏览 6 评论 0原文

我试图在应用程序域中创建一个对象:

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

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

无法将透明代理转换为类型“Mono.TextTemplated.CompiledTemplate”。

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

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

我尝试向 AppDomain 添加 AssemblyResolve 处理程序,该处理程序使用 Assembly.LoadFrom 显式加载文件名,但 CodeBase 的扩展名仍然为大写。由于原始程序集也是使用 Assembly.LoadFrom (通过 Mono.Addins)加载的,因此 CodeBase 值之间的差异看起来非常奇怪。

对于修复或解决此问题有什么建议吗?

I'm trying to create an object in an appdomain:

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

However, I always get the following error:

Unable to cast transparent proxy to type 'Mono.TextTemplating.CompiledTemplate'.

I'm running on .NET 4.0, not Mono, despite what the namespace might suggest :)

As far as I know, this error happens when .NET thinks that the Type & Assembly do not exactly match in the two domains. However, when debugging, the FullName and Location are identical. Only the Assembly.Codebase property differs - in the child AppDomain its extension is uppercased to "DLL" for some reason.

I've tried adding an AssemblyResolve handler to the AppDomain, which uses Assembly.LoadFrom to load the filename explicitly, but the CodeBase's extension still gets uppercased. Since the original assembly was also loaded with Assembly.LoadFrom (via Mono.Addins), the difference between the CodeBase values seems very strange.

Any suggestions for fixing or working around this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

极度宠爱 2024-09-25 04:13:07

您是否遇到了程序集加载上下文的问题?
(例如,请参见此处< /a>)
您有一个明显位于加载上下文中的类型(因为您使用的是 typeof(CompiledTemplate)),但您是说辅助 AD 中的类型已加载到加载源上下文中。 ..

您是否检查过 fuslogvw 来确定正在加载的程序集? Fuslog 跟踪还会告诉您程序集是否被加载到不同的上下文中。

Could you be running into an issue with assembly load contexts?
(e.g. see here)
You have a type that's clearly in the load context (because you're using typeof(CompiledTemplate)), but you're saying that the type in the secondary AD is loaded into the load-from context...

Did you check with fuslogvw to determine exactly what assemblies are being loaded? The fuslog trace will also tell you if the assemblies are being loaded into different contexts.

闻呓 2024-09-25 04:13:07

也许您可以使用 dynamic 关键字代替将其转换为特定类型:

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

这至少可以为您提供解决问题的方法。当然,潜在的缺点是没有编译时检查和/或性能较慢。但是,根据您的情况,这些权衡可能可以忽略不计。

Perhaps you can use the dynamic keyword instead of casting it to a specific type:

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

That might at least give you a workaround to the problem. Of course, the potential drawbacks will be not having compile time checking and/or slower performance. However, these might be negligible trade-offs depending on your situation.

缺⑴份安定 2024-09-25 04:13:07

事实上,程序集的第二个副本已按原样加载到内存中。

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

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

文件名略有不同(.DLL 扩展名大小写不同)意味着从两个位置加载相同的 DLL(即:GAC 不区分大小写/文件名 IIRC 始终为小写)。

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

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

这是新代码还是由于某种原因而失败的现有代码?

A second copy of the assembly is, indeed, being loaded into memory as it is.

An instance of a type in the runtime is specific to the instance of the assembly loaded - so even if the same DLL file is loaded in a second time, the types are not considered to match.

This is a typical problem when "DLLHell" is extended into the "GACAndDLLHell". "GACONLYHeaven" is a better place ... :).

That the filenames are subtly different (the .DLL extension has a different case) implies that the same DLL is being loaded from two places (that is: the GAC is case-insensitive/always lower case on filenames IIRC).

An abstract class or, preferably, an interface is what you need here.

If you can't make changes to the code base I would, first, make very sure that the DLL exists in only 1 place on the drive (or 0 places on the drive if it is being loaded from the GAC). A copy of the DLL that contains the type: 'CompiledTemplate' in your app /bin folder would be a real culprit ...?

Is this new code or existing code that is now failing for some reason?

最美不过初阳 2024-09-25 04:13:07

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

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

I have a WCF net named pipes application that uses a callback (duplex) architecture.

I got this error because my service interface's [ServiceContract] was annotated with the wrong callback.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文