为什么从加载的DLL访问静态值和主应用访问的结果存在差异?
问题根本原因
静态变量的唯一性由「类型所属的程序集实例 + 程序集加载的上下文」共同决定,你当前环境中存在两份独立的StaticValues类型实例,主程序和插件访问的并不是同一个静态属性。
具体触发逻辑
- 你的两个插件项目大概率将
StaticValues所在的SomeStaticValues程序集的「复制本地」属性设为了true,插件存放目录下存在一份SomeStaticValues.dll文件。 - 你使用
Assembly.LoadFrom方法加载插件时,LoadFrom会优先从插件DLL所在目录加载依赖,会把插件目录下的SomeStaticValues.dll加载到LoadFrom上下文中。而主程序引用的SomeStaticValues.dll是从主程序运行目录加载到默认Load上下文的,两份程序集属于不同的加载上下文,对应的StaticValues类型是互相独立的,静态属性自然不共享。 - 两个插件从同一个目录加载,所以共用LoadFrom上下文中的同一份
SomeStaticValues程序集,因此XY插件调用SetValue修改值后,AB插件读取到的是修改后的值,而主程序修改自己上下文的静态值,插件完全感知不到,就出现了你遇到的输出结果。
解决方法
- 方法1:将所有插件项目中
SomeStaticValues程序集的「复制本地」属性改为false,插件存放目录不要放SomeStaticValues.dll。这样LoadFrom加载插件时找不到本地依赖,会自动使用主程序已经加载到默认上下文的公共程序集,所有地方访问的静态属性就会统一。 - 方法2:改用
Assembly.Load而非Assembly.LoadFrom加载插件,让插件的所有依赖都走默认Load上下文加载,也会复用主程序已经加载的公共程序集。
内容的提问来源于stack exchange,提问作者moo.h
相关产品推荐
相关产品推荐

