一个大型asp.net 4应用程序出现了一个非常奇怪的问题。IIS有时不会从影子复制位置加载模块,而是从dll最初来源的bin目录加载模块。
有没有人知道IIS模块加载是如何工作的,这是正常的行为还是一个错误?
这给我们带来的问题
- dev;相应的dll被锁定在bin文件夹中,这意味着msbuild不能在构建时替换它。
- 这给我们带来了一个特别讨厌的(而且很难找到的)问题(我们正在用一个hack来解决这个问题),我们在nhibernate查询中得到TypeMismatchException
- ASP。. NET 4应用程序在Win7上运行;WinServer2008R2, IIS 7.5,多个项目使用MVC3, MVC4, WebForms, WebApi
- 通过附加VS调试器和检查加载模块获取的模块信息
- 如果我执行isreset并清除临时asp.net文件文件夹,然后启动应用程序,那么dll将全部复制到影子复制位置,然后从那里加载。如果我再次执行isreset并启动应用程序,则模块将从bin位置加载,而不是从影子复制位置加载
- 这只影响web项目的项目依赖,入口点总是从影子拷贝位置加载。即项目。Web将从影子拷贝位置加载,这是该项目的项目依赖项。BusinessLogic ,项目。DataAccess将从bin文件夹加载,外部依赖项(automapper, glimpse等)将从影子副本位置加载。
- 我们没有重写任何应用程序池或应用程序域配置的代码,web。配置或IIS配置(默认设置)
- 找不到模块加载或应用启动的详细记录。
几周前发现了这个问题的根本原因,现在发帖希望能帮助任何遭受类似问题的人。
经过几个开发人员的深思熟虑,我们发现这是由于我们扫描dll以获取非休眠配置的方式造成的。
当我们显式地从代码中加载dll时,我们误用了Assembly
helper方法。我们不用Assembly.LoadFrom(assemblyPath)
,而是用Assembly.LoadFile(assemblyPath)
。这些方法之间有很多不同之处,这里相关的是LoadFile()
加载指定的文件,而LoadFrom()
将应用逻辑从其他位置(如temp, cache或GAC)查找程序集。有关差异的更多详细信息,请参阅此问题。
总之,在修改了这一行代码之后,我们所有的问题都消失了。