在我的单元测试中使用NHibernate 3.1和Moq 4.0.10827,所有这些在.NET 4.0中运行,如果测试都在同一个域中一个接一个地运行,我会收到以下错误:
NHibernate.HibernateException:创建代理实例失败 ----> System.InvalidCastException:无法将类型为“System .__ ComObject”的COM对象强制转换为接口类型“Microsoft.Runtime.Hosting.IClrStrongName”。此操作失败,因为对于具有IID“{9FD93CCF-3280-4391-B3A9-96E1CDE77C8D}”的接口的COM组件的QueryInterface调用由于以下错误而失败:接口未注册(HRESULT异常:0x80040155)。
当我运行与不使用Moq的测试时,此错误不会失败。
有趣的是,当我仍然使用Moq的.NET 3.0版本时,当我运行一系列Moq测试时,我得到了类似的cast COM object...
错误。我从此切换到Moq的4.0版本。
我有关此错误的一些信息(在故障排除中看看底部附近): http://blogs.msdn.com/b/clrteam/archive/2010/06/23/in-proc-sxs-and-migration-quick-start.aspx
具体来说,它说:
如果您的应用程序通过.NET运行时的托管互操作层实例化并使用COM组件,并且其中一个COM组件恰好被管理,那么迁移应用程序后很可能会遇到类似于[上面的错误]。
由于以下两个组合条件,可能会发生此错误:
托管COM组件是根据与实例化调用者不同的.NET Runtime版本注册的,导致它在另一个运行时激活而不是实例化调用者。
- 醇>
接口未使用System.Runtime.InteropServices.ComVisibleAttribute标记,值为true。
由于运行时优化,此方案过去有效:当.NET运行时注意到它实例化的COM类型具有托管实现,并且它实例化为与实例化调用者相同的应用程序域时,它绕过了托管互操作层并将受管对象本身返回给调用者。在以前的.NET Framework版本中(其中进程内SxS不可用),所有托管COM类型及其托管客户端通常被加载到同一个应用程序域中,从而允许返回实现托管对象,并允许接口转换成功而不被标记为ComVisible。
迁移应用程序可以轻松创建条件1;如果应用程序还依赖于条件2(这不常见),则会遇到上述错误。有几种解决方案可供选择:
获取托管COM类型的更新版本,该版本正确地将接口声明为ComVisible。
- 醇>
更新应用程序配置文件以使用useLegacyV2RuntimeActivationPolicy扩展名。
似乎它们可能是.NET 4中的Castle DynamicProxy不喜欢的东西?我找到了a message on the Castle mailing list,暗示了这一点。
我尝试使用单元测试程序集的app.config(ReSharper 6)中的useLegacyV2RuntimeActivationPolicy="true"
开关。我也在原生NUnit跑步者中尝试了相同的开关。
有什么想法吗?