How to serialize/deserialize an object loaded from another assembly?

前端 未结 2 2116
我在风中等你
我在风中等你 2020-12-08 08:45

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

Interfaces.cs (from a referenced assembly, Interfaces

相关标签:
2条回答
  • 2020-12-08 09:28

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

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

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

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

    And deserialization 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();
      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;
     }
    }
    
    0 讨论(0)
  • 2020-12-08 09:32

    Do you want to (de)serialize using binary format? If no you may use the following:

    P.S. This is not an solution but some kind of workaround.

    Some assembly

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

    public interface ISettings : ISerializable
    {
        DateTime StartDate { get; }
    }
    
    public class SerializeHelper<T>
    {
        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);
    

    Some other assembly

    public interface ISomeOtherInterface
    {
    ISettings Settings { get; set; }
    }
    
    public class DeSerializeHelper<T>
    {
        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<SomeOtherInterfaceImplementation>(@"%temp%\sample.xml")
    
    0 讨论(0)
提交回复
热议问题