无法将泛型类型加载到 ASP.NET 应用程序中的另一个 AppDomain

Posted

技术标签:

【中文标题】无法将泛型类型加载到 ASP.NET 应用程序中的另一个 AppDomain【英文标题】:Unable to load a generic type into another AppDomain in ASP.NET Application 【发布时间】:2012-10-31 00:56:54 【问题描述】:

我有一个非常奇怪的问题,在 ASP.NET 中运行时,我无法将泛型类型加载到另一个 AppDomain 中,但它可以在我的测试项目和控制台应用程序中使用。

相关代码基本上是这样做的:

Assembly ass = Assembly.GetExecutingAssembly();
string AssemblyPath = ass.Location;

var templateType = typeof(RazorEngine<RazorTemplateBase>);

object instance = LocalAppDomain.CreateInstanceFrom(AssemblyPath,
                                             templateType.FullName)
                                .Unwrap();

最后一行的代码炸弹。 AppDomain 存在,其基本执行和 bin 路径与原始 AppDomain 匹配。

在测试项目中运行此代码时,它工作正常。实例已创建(作为 TransparentProxy 远程引用),一切正常。

在 ASP.NET 中运行时,泛型类型参数出现类型错误:

GenericArguments[0], 'Westwind.RazorHosting.RazorTemplateBase', on 'Westwind.RazorHosting.RazorEngine`1[TBaseTemplateType]' 违反了 'TBaseTemplateType' 类型的约束。

其中 TBaseTemplateType 与传入的类型相同(即 RazorTemplateBase),RazorEngine 定义如下:

public class RazorEngine<TBaseTemplateType> : MarshalByRefObject
    where TBaseTemplateType : RazorTemplateBase

显然我传递了正确的类型,因为它是实际的限制类型,但不知何故 AppDomain 没有将 Generic 类型识别为相同的类型。

正如我提到的,它在 Windows 应用程序和测试项目中工作,但在 ASP.NET 中,泛型类型不会跨 AppDomain 边界进行实例化。使用相同的代码创建一个非泛型类型(甚至是继承自 RazorHosting 的该类型 RazorHosting 的相同非泛型版本)并且工作正常。

难住了。 ASP.NET 可以做些什么来使其行为与在测试项目中运行时如此不同?

【问题讨论】:

我认为罗素是对的。这可能是卷影复制问题。尝试用 templateType.Assembly.Location 替换 AssemblyPath。 【参考方案1】:

我以前遇到过这个奇怪的问题。它似乎归结为 Shadow Copy(ASP.NET 默认使用)、每个 AppDomain 的 ApplicationBase 和 Load Contexts 的组合。

我的大脑中出现这个问题已经有一段时间了,但请查看我对这个问题的回答,看看是否有帮助:

Domain problems

【讨论】:

以上是关于无法将泛型类型加载到 ASP.NET 应用程序中的另一个 AppDomain的主要内容,如果未能解决你的问题,请参考以下文章

将泛型类型转换为具体类型时出错

将泛型 T 的类型解析为 C# 中的特定接口

为啥 C# 允许将泛型数组与所有类型的模式进行匹配?

是否可以将泛型重载限制为属性类型?

如何将泛型类型参数限制为 System.Enum [重复]

Java 将泛型类型与 Void 进行比较