2010-05-24 47 views
2

我编写了一个插件系统,并且我想保存/加载它们的属性,以便在程序重新启动时它们可以继续工作。我使用二进制序列化。问题是他们可以被序列化但不是反序列化。 在反序列化期间“无法找到程序集”异常被抛出。我怎样才能恢复序列化的数据?在C中对外部​​程序集进行序列化和反序列化#

+0

是否状态,这集不会被发现? – Snake 2010-05-24 13:55:00

+0

是的。我写的一个插件。但是它已经加载了,那么它如何序列化呢? – Heka 2010-05-24 13:57:34

+0

我愿意打赌,你的插件程序集并不是在反序列化时加载的。我知道你刚才说过,但我会敦促你再看一遍。 – 2010-05-24 15:17:49

回答

4

确定这里我找到了一些东西。 :)

http://techdigger.wordpress.com/2007/12/22/deserializing-data-into-a-dynamically-loaded-assembly/

我用这种方法,它的工作没有任何问题。

杉杉定义粘合剂类:

internal sealed class VersionConfigToNamespaceAssemblyObjectBinder : SerializationBinder { 

     public override Type BindToType(string assemblyName, string typeName) { 

     Type typeToDeserialize = null; 

     try{ 

     string ToAssemblyName = assemblyName.Split(',')[0]; 

     Assembly[] Assemblies = AppDomain.CurrentDomain.GetAssemblies(); 

     foreach (Assembly ass in Assemblies){ 

      if (ass.FullName.Split(',')[0] == ToAssemblyName){ 

       typeToDeserialize = ass.GetType(typeName); 

       break; 

      } 

     } 

     } 

     catch (System.Exception exception){ 

     throw exception; 

     } 

     return typeToDeserialize; 

     } 

    } 

然后序列化方法:

  public static byte[] Serialize(Object o){   

      MemoryStream stream = new MemoryStream(); 

      BinaryFormatter formatter = new BinaryFormatter(); 

      formatter.AssemblyFormat 

       = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; 

      formatter.Serialize(stream, o); 

      return stream.ToArray(); 

      } 


      public static Object BinaryDeSerialize(byte[] bytes){ 

       MemoryStream stream = new MemoryStream(bytes); 

       BinaryFormatter formatter = new BinaryFormatter(); 

       formatter.AssemblyFormat 

        = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; 

       formatter.Binder 

        = new VersionConfigToNamespaceAssemblyObjectBinder(); 

       Object obj = (Object)formatter.Deserialize(stream); 

       return obj; 

      } 

我使用他们,我需要。

  protected void SaveAsBinary(object objGraph, string fileName) 

      { 

       byte[] serializedData = Serialize(objGraph); 

       File.WriteAllBytes(fileName, serializedData); 

      } 


      protected object LoadFomBinary(string fileName) 

      {  

       object objGraph = null; 

       try 

       { 

       objGraph = BinaryDeserialize(File.ReadAllBytes(fileName)); 

       } 

       catch (FileNotFoundException fne) 

       { 

      #if DEBUG 

       throw fne; 

      #endif 

       }  

       return objGraph; 

      } 

感谢您的帮助:)

2

使用fuslogvw.exe工具找出CLR正在搜索程序集的位置。

+0

感谢它是一个非常有用的工具:) – Heka 2010-05-25 07:11:51

1

很可能,在您反序列化数据时,您的插件程序集未加载。因为它是一个外部的插件程序集,所以我猜你明确地加载了它。您可能在加载程序集之前反序列化属性对象。您可以通过在当前的AppDomain上挂接AssemblyResolve和AssemblyLoad事件来诊断和修复问题,并在调用它们时精确地观察它们。

您还可以使用AssemblyResolve通过自己放置显式的Assembly加载代码并返回加载的程序集来修复加载错误。我不建议这样做,因为它有些倒退。

AssemblyResolve

+0

其实我加载程序集后调用反序列化。 – Heka 2010-05-25 07:12:49