AppDomain.CurrentDomain.Evidence会引发SerializationException

时间:2015-01-23 18:39:17

标签: c# .net

使用ReSharper(8.2.2)和VS 2013运行我的测试用例时出现了一个奇怪的错误。

演示问题的简化测试用例只包含两行代码:

CallContext.LogicalSetData("mydata", new ActivityStack());
var evidence = AppDomain.CurrentDomain.Evidence;

其中ActivityStack是可序列化的自定义类型。当测试用例通过ReSharper运行时,第二行会抛出异常:

System.Runtime.Serialization.SerializationException was unhandled by user code
  HResult=-2146233076
  Message=Type is not resolved for member 'CSG.Framework.Operations.ActivityStack,CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223'.
  Source=mscorlib
  StackTrace:
       at System.AppDomain.get_Evidence()
       at System.AppDomain.get_Evidence()
       at CSG.Framework.Utilities.AppDomainLauncher`1..ctor(String appDomainName) in d:\Work\Git\Framework\Src\Library\Framework\Utilities\AppDomainLauncher.cs:line 40
       at CSG.Framework.UnitTest.AppDomainLauncherTests.LaunchClassFromCallingAssembly() in d:\Work\Git\Framework\Src\Library\Framework.UnitTest\Utilities\AppDomainLauncherTests.cs:line 52
  InnerException: 

即使当前的AppDomain似乎在BaseDirectory上有正确的路径,其中可以找到包含该类型的程序集,CLR似乎仍然使用ReSharper bin路径根据Fusion日志探测程序集。如果我将程序集复制到ReSharper bin文件夹,问题就会消失,但我不认为这是正确的解决方案。我试图在当前的AppDomain上订阅AssemblyResolve事件,但是没有调用处理程序。

Fusion日志:

*** Assembly Binder Log Entry  (1/23/2015 @ 12:28:54 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:     C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Program Files (x86)\JetBrains\ReSharper\v8.2.Qiwabic\Bin\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = JetBrains.ReSharper.TaskRunner.CLR45.x64.exe Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files (x86)\JetBrains\ReSharper\v8.2.Qiwabic\Bin\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework/CSG.Framework.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework/CSG.Framework.EXE.
LOG: All probing URLs attempted and failed.

2 个答案:

答案 0 :(得分:7)

这个linke(https://msdn.microsoft.com/en-us/library/dn458353(v=vs.110).aspx)解释了根本原因。

涉及两个应用程序域:默认应用程序域(ReSharper runner)和当前应用程序域(测试用例)。在当前应用程序域中执行AppDomain.Evidence时:

  • 它会查找当前应用域的证据。
  • 它会尝试计算当前应用域的证据 基于当前域名。
  • 获取当前域证据的调用会触发a 从当前应用程序域到默认的跨应用程序域调用 应用域名。
  • 作为.NET Framework中跨应用程序域合同的一部分, 逻辑调用上下文的内容也必须进行封送处理 应用域边界。

由于无法在默认应用程序域中解析逻辑调用上下文中的类型(ActivityStack),因此会抛出异常。

答案 1 :(得分:1)

我有类似的问题。如果您将订单更改为:

var evidence = AppDomain.CurrentDomain.Evidence;
CallContext.LogicalSetData("mydata", new ActivityStack());

它会起作用。在我的项目中,我创建了一个Mocked Principal并在设置步骤中分配给Thread.CurrentPrincipal。当我在AppDomain.Evidence调用之后移动该赋值时(这是NHibernate的自动调用)。有用 :) 希望它有所帮助