如何序列化/反序列化从另一个程序集加载的对象?

我想序列化/反序列化已由从程序集加载的另一个对象实例化的对象:

Interfaces.cs(来自引用的程序集,Interfaces.dll)

public interface ISomeInterface { ISettings Settings { get; set; } } public interface ISettings : ISerializable { DateTime StartDate { get; } } 

SomeClass.cs(来自引用的程序集,SomeClass.dll)

 public class SomeClass : ISomeInterface { private MySettings settings = new Settings(); public ISettings Settings { get { return (ISettings)settings; } set { settings = value as MySettings; } } } [Serializable] public class MySettings : ISettings { private DateTime dt; public MySettings() { dt = DateTime.Now; } protected MySettings(SerializationInfo info, StreamingContext context) { dt = info.GetDateTime("dt"); } [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("dt", dt); } public DateTime StartDate { get { return startFrom; } internal set { startFrom = value; } } } 

启动项目:

 [Serializable] public class ProgramState } public ISettings Settings { get; set; } } 

在启动项目中,最终我将ProgramState实例的Settings设置为SomeClass的Settings。 然后我继续使用以下命令进行序列化:

 public void SerializeState(string filename, ProgramState ps) { Stream s = File.Open(filename, FileMode.Create); BinaryFormatter bFormatter = new BinaryFormatter(); bFormatter.Serialize(s, ps); s.Close(); } 

这不会引发任何exception。 我反序列化:

 public ProgramState DeserializeState(string filename) { if (File.Exists(filename)) { ProgramState res = new ProgramState(); Stream s = File.Open(filename, FileMode.Open); BinaryFormatter bFormatter = new BinaryFormatter(); try { res = (ProgramState)bFormatter.Deserialize(s); } catch (SerializationException se) { Debug.WriteLine(se.Message); } s.Close(); return res; } else return new ProgramState(); } 

这会抛出exception,我的Debug输出中会出现以下内容:

mscorlib.dll中发生了’System.Runtime.Serialization.SerializationException’类型的第一次机会exception
无法找到程序集’SomeClass,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null’。

我确定在调用DeserializeState之前已经加载了包含SomeClass的程序集,那么为什么它会抛出一个无法找到它的exception呢?

我一直在寻找一些教程,但是我能够找到的只能处理来自同一个程序集的类(另外,我对.NET中的序列化和反序列化过程的理解很少 – 一个详细解释的链接可能是有用)。

在此期间,有没有办法使这个正确反序列化MySettings对象?

在探索了一些之后(即谷歌搜索答案),我能够解决这个问题。 这是修改后的代码:

Interfaces.cs(来自引用的程序集,Interfaces.dll)

 public interface ISomeInterface { ISettings Settings { get; set; } } public interface ISettings { DateTime StartDate { get; } } 

SomeClass.cs(来自引用的程序集,SomeClass.dll)

 public class SomeClass : ISomeInterface { private MySettings settings = new Settings(); public ISettings Settings { get { return (ISettings)settings; } set { settings = value as MySettings; } } } [Serializable] public class MySettings : ISettings { private DateTime dt; public MySettings() { dt = DateTime.Now; } public DateTime StartDate { get { return startFrom; } internal set { startFrom = value; } } } 

序列化完成:

 public void SerializeState(string filename, ProgramState ps) { Stream s = File.Open(filename, FileMode.Create); BinaryFormatter bFormatter = new BinaryFormatter(); bFormatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; bFormatter.Serialize(s, ps); s.Close(); } 

并反序列化:

 public ProgramState DeserializeState(string filename) { if (File.Exists(filename)) { ProgramState res = new ProgramState(); Stream s = File.Open(filename, FileMode.Open); BinaryFormatter bFormatter = new BinaryFormatter(); bFormatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; bFormatter.Binder = new MyBinder(); // MyBinder class code given below try { res = (ProgramState)bFormatter.Deserialize(s); } catch (SerializationException se) { Debug.WriteLine(se.Message); } s.Close(); return res; } else return new ProgramState(); } 

这个课程已添加。 这是二进制格式化程序的绑定程序:

 internal sealed class MyBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { Type ttd = null; try { string toassname = assemblyName.Split(',')[0]; Assembly[] asmblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly ass in asmblies) { if (ass.FullName.Split(',')[0] == toassname) { ttd = ass.GetType(typeName); break; } } } catch (System.Exception e) { Debug.WriteLine(e.Message); } return ttd; } } 

你想(二)使用二进制格式序列化吗? 如果不是,您可以使用以下内容:

PS这不是解决方案,而是某种解决方法。

一些assembly

公共接口ISomeInterface {ISettings Settings {get; 组; }}

 public interface ISettings : ISerializable { DateTime StartDate { get; } } public class SerializeHelper { public static void Serialize(string path, T item) { var serializer = new XmlSerializer(typeof(T)); using (TextWriter textWriter = new StreamWriter(path, false, Encoding.UTF8)) { serializer.Serialize(textWriter, T item); } } } SerializeHelper.Serialize(@"%temp%\sample.xml", instanceOfISomeInterface); 

其他一些assembly

 public interface ISomeOtherInterface { ISettings Settings { get; set; } } public class DeSerializeHelper { public static T Deserialize(string path) { T instance = default(T); var serializer = new XmlSerializer(typeof(TestData)); using (TextReader r = new StreamReader(path, Encoding.UTF8)) { instance = (T)serializer.Deserialize(r); } return instance; } } ISomeOtherInterface instance = DeSerializeHelper.Deserialize(@"%temp%\sample.xml")