Сериализация и десериализация внешней сборки в C # - PullRequest
2 голосов
/ 24 мая 2010

Я написал систему плагинов и хочу сохранить / загрузить их свойства, чтобы при перезапуске программы они могли продолжать работать.Я использую двоичную сериализацию.Проблема в том, что они могут быть сериализованы, но не десериализованы.Во время десериализации выдается исключение «Невозможно найти сборку».Как я могу восстановить сериализованные данные?

Ответы [ 3 ]

4 голосов
/ 25 мая 2010

Хорошо, я кое-что нашел. :)

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 голосов
/ 24 мая 2010

Используйте инструмент fuslogvw.exe, чтобы узнать, где CLR ищет сборку.

1 голос
/ 24 мая 2010

Скорее всего, ваша сборка плагина не загружается во время десериализации данных. Поскольку это внешняя сборка плагина, я предполагаю, что вы явно загружаете ее. Вы, вероятно, десериализуете объект свойств перед загрузкой сборки. Вы можете диагностировать и устранить проблему, подключив события AssemblyResolve и AssemblyLoad к текущему домену приложений и точно наблюдая, когда они вызываются.

Вы также можете использовать AssemblyResolve, чтобы исправить ошибку загрузки, поместив в нее явный код загрузки сборки и вернув загруженную сборку. Я не рекомендую это, потому что это немного наоборот.

AssemblyResolve

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...