如何序列化/反序列化从另一个组件装入的对象? [英] How to serialize/deserialize an object loaded from another assembly?

查看:224
本文介绍了如何序列化/反序列化从另一个组件装入的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to serialize/deserialize an object that has been instantiated by another object loaded from an assembly:

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

Interfaces.cs (from a referenced assembly, Interfaces.dll)

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

public interface ISettings : ISerializable
{
 DateTime StartDate { get; }
}

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

SomeClass.cs (from a referenced assembly, 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的一个实例的设置,以SomeClass的设置。然后,我继续使用做序列化:

In the startup project, eventually I set Settings of an instance of ProgramState to Settings of SomeClass. I then go on to do the serialization using:

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

这不会引发任何异常。我用反序列化:

This doesn't throw any exceptions. I deserialize with:

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();
}

这抛出异常,在我调试输出画面显示如下:

This throws an exception and the following appears in my Debug output:

类型的'System.Runtime.Serialization.SerializationException'第一次机会异常出现在mscorlib.dll结果
无法找到程序集​​SomeClass的,版本= 1.0.0.0,文化=中立,公钥=空'。

A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Unable to find assembly 'SomeClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

我敢肯定,含SomeClass的组装已经调用DeserializeState之前加载,所以为什么它抛出一个异常,它无法找到它?

I'm sure that the assembly containing SomeClass has been loaded before the call to DeserializeState, so why is it throwing an exception that it is unable to find it?

我一直在寻找一些教程,但是那些我能才发现处理类都是从同一个程序集(加,我在.NET序列化和反序列化过程的理解是最小的 - 一个链接到一个详细解释可能是有益的)。

I've been looking at some tutorials, but the ones I was able to find only deal with classes from the same assembly (plus, my understanding of the serialization and deserialization process in .NET is minimal - a link to a detailed explanation might be helpful).

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

In the meantime, is there any way to make this correctly deserialize the MySettings object?

推荐答案

周围的一些更戳(即google搜索的答案)后,我能解决这个问题。下面是修改code:

After poking around some more (i.e. googling the answer), I was able to resolve this. Here is the modified code:

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

Interfaces.cs (from a referenced assembly, Interfaces.dll)

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

public interface ISettings
{
 DateTime StartDate { get; }
}

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

SomeClass.cs (from a referenced assembly, 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; }
 }
}

序列化与完成的:

Serialization is done with:

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();
}

加入这个类。这是用于二进制格式化粘合剂:

This class was added. This is the binder for the binary formatter:

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;
 }
}

这篇关于如何序列化/反序列化从另一个组件装入的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆