如何序列化/反序列化从另一个组件装入的对象? [英] How to serialize/deserialize an object loaded from another assembly?
问题描述
我想序列化/反序列化已经通过实例从一个程序集加载的另一个对象的对象:
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屋!