.NET 6迁移后XmlSerializer实例化抛出程序集引用异常
解决.NET 6下Excel-DNA中XmlSerializer的“non-collectible assembly”异常问题
问题根源
.NET Framework中XmlSerializer动态生成的序列化程序集默认是非可回收的,与Excel-DNA的加载上下文兼容;但.NET 6+默认生成**可回收(collectible)**的动态程序集,而Excel-DNA加载的插件程序集处于非可回收上下文,两者引用时就会抛出a non-collectible assembly may not reference a collectible assembly异常。找不到system.private.corelib.xmlserializers.dll是因为运行时尝试为List<Config>这类包含系统泛型类型的集合生成序列化程序集,而系统核心库无法生成对应序列化程序集,进一步触发了上下文冲突。
可行解决方案
1. 预生成XmlSerializer程序集
使用sgen.exe工具提前为你的类型生成序列化程序集,避免运行时动态生成:
- 找到.NET 6对应的
sgen.exe路径(通常在C:\Program Files\dotnet\sdk\6.0.x\bin目录下) - 执行命令生成序列化程序集:
sgen.exe /a:你的插件程序集.dll /t:System.Collections.Generic.List`1[你的命名空间.Config] - 将生成的
你的插件程序集.XmlSerializers.dll与Excel-DNA插件一起部署
2. 改用DataContractSerializer替代XmlSerializer
DataContractSerializer不会生成动态程序集,从根源避免上下文冲突,示例代码:
using System.Runtime.Serialization; using System.Xml; // 为Config类添加特性 [DataContract] public class Config { [DataMember] public string YourSetting { get; set; } // 其他配置属性... } // 序列化逻辑 var serializer = new DataContractSerializer(typeof(List<Config>)); using var writer = XmlWriter.Create("userSettings.xml"); serializer.WriteObject(writer, configList); // 反序列化逻辑 using var reader = XmlReader.Create("userSettings.xml"); var configList = (List<Config>)serializer.ReadObject(reader);
3. 强制XmlSerializer生成非可回收程序集
通过AppContext开关修改XmlSerializer的默认行为,需在创建第一个XmlSerializer实例前设置:
// 建议在Excel-DNA的AutoOpen方法开头添加 AppContext.SetSwitch("System.Xml.Serializer.GenerateNonCollectibleSerializerAssemblies", true); // 之后正常创建XmlSerializer XmlSerializer formatter = new XmlSerializer(typeof(List<Config>));
内容的提问来源于stack exchange,提问作者turhan
相关产品推荐
相关产品推荐

