2016-11-09 117 views
6

我正在使用一个Web API项目,该项目使用内部模拟框架,允许截取和修改控制器的响应。它使用MEF加载包含代码的程序集,如果某些前置条件匹配,则代码将被执行。为什么我无法调试动态加载的程序集?

我知道这是正常工作,因为我可以在响应中看到模拟已执行,但由于某种原因,我无法调试动态加载的程序集中的代码。尽管断点看起来很活跃,但执行永远不会在那里发生

The breakpoint is active

我打过电话Debugger.Break();,它确实打破,但调用堆栈显示为空,和Visual Studio仅显示这样的信息:

The application is in break mode

我可以看到,大会及其符号加载到模块窗口中:

Modules window shows that symbols were loaded correctly

我能够只是调用动态加载组件(在behavior参数),它看起来像在此之前打破:

private HttpResponseMessage ApplyBehavior(
    IMockBehavior behavior, 
    string controller, string action, 
    HttpRequestMessage request, 
    HttpResponseMessage mockedResponse) 
{ 
    return behavior.Apply(controller, action, request, mockedResponse); 
} 

如果我尝试检查behavior变量在即时窗口,Visual Studio的节目以下例外:

behavior.GetType() 
'behavior.GetType()' threw an exception of type 'System.IO.FileNotFoundException' 
    Data: {System.Collections.ListDictionaryInternal} 
    FileName: null 
    FusionLog: null 
    HResult: -2147024894 
    HelpLink: null 
    InnerException: null 
    Message: "Cannot load assembly 'SuperMam.WebAPI.Mocking'." 
    Source: null 
    StackTrace: null 
    TargetSite: null 

这是一个相当大的应用程序的一部分,我无法提取相关部分。我试图收集尽可能多的信息,但仍然不知道为什么会发生这种情况。

我能做些什么来解决这个问题?

编辑1

只是可以肯定,如果我叫从我的控制器代码,我能踏进去正常:

var behaviourType = AppDomain.CurrentDomain.GetAssemblies() 
    .First(a => a.FullName.Contains("SuperMam.WebAPI.Mocking")) 
    .GetType("SuperMam.WebAPI.Mocking.MyBehaviour"); 

var behavior = (IMockBehavior)Activator.CreateInstance(behaviourType); 
// I can step into this, and view the behaviour variable in the watch 
behavior.Apply("dummy", "dummy", Request, null); 

,但即使我这样做,当相同方法被模拟框架调用,我无法进入它。

编辑2

我还注意到,相同的组件(全名是相同的)被加载两次。在两个实例之间的区别是他们CodeBaseLocation属性:

  • 他们中的一个具有基本代码等于我的应用程序的bin目录和位置等于C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\...
  • 他们的另一个具有基本代码等于第一一个人的位置(C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\...),而位置是一个空字符串。

难道这是问题的原因?

+0

这个问题呢?你能分享你身边的最新信息吗? –

+0

它仍在发生。我相信这是由于程序集被加载两次,但我不知道如何防止它。 –

回答

0

原来,原因是程序集没有按照我的想法被MEF加载。它正在使用Assembly.Load(File.ReadAllBytes(mockDllPath))加载。由于程序集是从字节数组中加载的,所以调试器没有调试信息可用。

3

您试图动态加载的程序集是在您的系统上编译的?

为了调试动态加载的程序集,您需要在DLL旁边有一个PDB文件。该文件包含有关Visual Studio所需的程序集的调试信息。当您在调试模式下编译程序集时,PDB将自动在项目的./bin/Debug/文件夹中创建。如果您已将DLL移至其他位置,则尝试将PDB移至同一位置。

+0

PDB与DLL一起存在,正如Visual Studio能够加载调试符号所示(请参阅“模块”窗口截图)。 –

+0

这两个项目都是针对相同的框架版本? – sc3w

+0

是的,他们都是目标框架4.5 –

-1

问题应该是由于用于加载程序集的方法。

我想你正在使用:

Assembly.LoadFrom ...

尝试使用

Assembly.Load

+0

您使用哪种方法进行加载并不重要(ReflectionOnly除外)。唯一需要的是.pdb文件并以调试模式启动应用程序。 – Oliver

+0

'Load From'不允许正确加载pdb,而'load'方法则会加载。 –

+0

程序集由MEF加载(使用'[ImportMany]')。我不知道MEF是如何实现的,但我认为应该可以调试代码。 –

2

您的应用已进入休息状态,但目前没有代码被选中的调试引擎支持。

https://social.msdn.microsoft.com/Forums/en-US/99b43950-6c82-4945-ba16-04355abf9612/vs2015-breakpoints-dont-work?forum=vsdebug

如果可能的话,你可以检查它是否与调试选项/设置或设置VS:

我也遇到过这样的错误消息。

(1)VS2015的最新更新是更新3

(2)启用使用管理的兼容模式将针对此问题的目录。

+0

你的第二个建议结果非常有帮助。 *未来访问者* - 请参阅[this](https://stackoverflow.com/q/42158547/465053)文章中的屏幕快照,以便快速查看参考资料,以查看“托管兼容性模式”选项/设置的位置。 – RBT

相关问题