2015-01-23 5 views
3

я получил странную ошибку при выполнении моих тестовых случаев с помощью ReSharper (8.2.2) с VS 2013.AppDomain.CurrentDomain.Evidence бросает SerializationException

упрощенный тест случае, что демки проблема содержит только две строки кода:

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 для проверки сборки в соответствии с журналом Fusion. Проблема исчезнет, ​​если я скопирую сборку в папку bin ReSharper, но я не думаю, что это правильное решение. Я попытался подписаться на событие AssemblyResolve в текущем AppDomain, но обработчик не вызвал.

журнал 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. 
+0

Не уверен, что есть правильное решение, за исключением загрузки сборки в appdomain перед запуском теста (простой 'typeof' будет делать). – Will

+0

Пользовательский тип (ActivityStack) находится в той же сборке, что и выполняемый код (определенный в том же файле, что и тестовый пример), поэтому я считаю, что он уже должен быть загружен. – WenningQiu

+0

* Есть ли там внутреннее исключение? Может быть, здесь что-то еще происходит ... – Will

ответ

5

Это Линк (https://msdn.microsoft.com/en-us/library/dn458353(v=vs.110).aspx) объясняет причину.

Существует два домена приложения: домен приложения по умолчанию (бегун ReSharper) и текущий домен приложения (тестовый пример). Когда AppDomain.Evidence выполняется в текущем домене приложения:

  • Он ищет доказательства для текущего домена приложения.
  • Он пытается рассчитать доказательства для текущего домена приложения на основе текущего домена.
  • Звонок, чтобы получить подтверждение для текущего домена, вызывает вызов домена с доменом из текущего домена приложения в доменное приложение по умолчанию.
  • В рамках контракта с доменом кросс-приложения в .NET Framework содержимое контекста логического вызова также должно быть маршалировано через границы домена приложения.

Поскольку тип (ActivityStack), который находится в контексте логического вызова, не может быть разрешен в домене приложения по умолчанию, генерируется исключение.

1

У меня был подобный выпуск. Если вы смените заказ на:

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

Он будет работать. В моем проекте я создал Mocked Principal и назначил Thread.CurrentPrincipal на этапе настройки. Когда я перемещаю это назначение после вызова AppDomain.Evidence (это автоматический вызов NHibernate). Он работает :) Надеюсь, что это поможет

Смежные вопросы