为什么XmlSerializer.Serialize()查找具有特定版本的引用程序集?

时间:2017-09-25 08:19:50

标签: c# .net serialization dll

我们有一个具有以下文件夹部署层次结构的项目:

  • [文件夹]主要
    • MAIN.EXE
  • [文件夹]任务
    • TaskA.dll
    • Model.dll

Main.exe看起来像这样:

static void Main(string[] args)
{
    var assemblyPath = args[0];
    var className = args[1];

    IBatch batch = Assembly
        .LoadFrom(assemblyPath)
        .CreateInstance(className) as IBatch;

    batch.Execute();
}

TaskA.dll中,我们想将以下类的实例序列化为XML: (class Task中定义了TaskA.dllenum Model.Kind中定义了Model.dll

public class Task
{
    public Source? Source { get; set; }
    public int? Id { get; set; }
    public Model.Kind? Kind { get; set; }
}

序列化代码如下所示:

var xmlSerializer = new XmlSerializer(typeof(Task));

StringBuilder xmlStringBuilder = new StringBuilder();

using (var writer = new StringWriter(xmlStringBuilder))
{
    xmlSerializer.Serialize(writer, task);
}

var result = xmlStringBuilder.ToString();

首先执行正常。但是,如果我们将Model.dll1.0.1708.401替换为1.0.1709.101,则会引发以下异常:

System.InvalidOperationException: There was an error generating the XML document. --->
System.IO.FileNotFoundException: 
Could not load file or assembly 'Model, Version=1.0.1708.401, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
The system cannot find the file specified. 
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterTask.Write3_Task(String n, String ns, Task o, Boolean isNullable, Boolean needType) 
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterTask.Write4_Task(Object o) 
--- End of inner exception stack trace --- 
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id) 
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces) 

虽然可以通过注册AssemblyResolve事件处理程序来返回非特定版本程序集来修复它:

AppDomain.CurrentDomain.AssemblyResolve += (sender, arg) =>
{
    var path = Path.Combine(
        Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
        $"{new AssemblyName(arg.Name).Name}.dll");

    return Assembly.LoadFrom(path);
};

我们仍然很好奇为什么XmlSerializer.Serialize()首先寻找特定版本?

0 个答案:

没有答案