Search code examples
c#serializationassembliesexternal-assemblies

Serializing and Deserializing External Assembly in C#


I wrote a plugin system and I want to save/load their properties so that if the program is restarted they can continue working. I use binary serialization. The problem is they can be serialized but not deserialized. During the deserialization "Unable to find assembly" exception is thrown. How can I restore serialized data?


Solution

  • Ok here I have found something. :)

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

    I used this approach and it worked without any problem.

    Firs defined a binder class:

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

    And then serialization methods:

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

    And I use them where I need.

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

    Thanks for help :)