解决NopCommerce 在iis缓存目录Temporary ASP.NET Files下存在两个版本的dll问题(一)
前些天抽包更新之后,检查包文件没有问题,但是站点一直报错,提示找不到本次更新添加入的类,搞得一头雾水。再度检查包文件也没发现有问题。最后去查了下iis的缓存目录Temporary ASP.NET Files,才发现竟然有两个版本的dll,
如下图所示,存在两个编译时间不同的dll,而iis启用的还是旧版本的dll,导致新加入的类找不到所以一直报错。
停掉IIS程序池,然后将整个缓存目录删掉,启动IIS程序池,站点开始能正常使用。
原本以为解决了,但是没过多久,又开始出现这个问题,但是这自上次删除缓存目录之后没并有更新站点!
这下受打击了,决心要找出问题来!
反复在代码层面寻找原因,但是没有结果,唯一的收获就是PluginManager这个类会将插件输出目录里的dll复制到iis缓存目录下,但是经调试发现这仅限于复制插件类库本身生成的dll,不会复制插件引用的dll。
于是在想会不会是插件目录里有旧的dll,结果一看还真是。最后在一个插件输出目录下发现了旧版本的dll,把这里的dll覆盖或者删除,就不有再出现两个版本dll的情况了。
问题到此算是解决了。可为什么当时把整个iis缓存目录去掉后就正常没有出现两个版本的dll呢?难道是人性的缺失或者道德的沦丧?
为了一探究竟,只好拿出旧版的dll在开发环境试图重现。把旧dll复制到插件的输出目录下,清空掉iis缓存目录,然后开始调试。
第一次调试,没有问题(之前开发环境就没出问题,因为开发习惯编译整个解决方案,各个目录的dl版本l始终是统一的)。关掉后再试调,终于出现了,插件输出目录下的一堆dll文件全被复制到iis缓存目录下,也插件输入目录里的旧版dll也被复制过来,iis开始使用旧了dll,然后就开始报错!这也可以解释,当时在站点删除缓存目录后为什么只是一时解决了问题,因为只要iis回收或者重启,这些插件输出目录下的旧dll就会重新被复制到iis缓存目录下。
也就是说,只要nopcommerce的插件输出目录存在旧的dll,你更新的时候就必须要更新插件输出目录。这与大家习惯的抽包抽出的dll只更新站点bin目录的习惯并不同,所以这个问题是应该普遍存在的。这种重要的问题nopcommerce官方会不知道么?官方应该是知道这个问题的,因为我查看了下官方自带的插件,其输出目录只会输出一个dll文件:
于是去查阅官方的开发者文档插件开发demo,发现一条重要提示:
重要提示:确保所有第三方引用的“复制本地”属性设置为False(不复制),包括核心类库如:Nop.Service或者Nop.Web.Framework.dll。
原来官方早就打了预防针了,不过没说明原因和后果,所以也没细看,惭愧。
把所有插件的引用的“复制本地”属性全部设置为False(不复制),这样就能确保所有插件编译后只输出插件这个类库本身的dll,这样就不会再出现这个问题了。
注意:还要把站点的插件目录下的引用的第三方dll删掉,不然对于抽包更新来说,这些的dll就是个隐患。