我们有一个具有以下文件夹部署层次结构的项目:
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.dll
,enum 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.dll
从1.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()
首先寻找特定版本?