Независимая от сборки сериализация в .NET - PullRequest
8 голосов
/ 23 августа 2011

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

Ответы [ 3 ]

7 голосов
/ 23 августа 2011

Попробуйте это:

public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        return Type.GetType(String.Format("{0}, {1}", typeName, Assembly.GetExecutingAssembly().FullName));
    }
}
formatter.Binder = new CurrentAssemblyDeserializationBinder();
formatter.Deserialize(inStream);

Добавлен постер темы:

Да, это работает. Просто убедитесь, что в двоичных данных присутствуют какие-либо типы System.Generic или других библиотек, и вы должны передать их без изменений. «ResizableControls» - имя старой сборки сборки, «EntityLib» - имя новой сборки Кроме того, номер версии также должен быть заменен по требованию.

public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        string name;
        if (assemblyName.Contains("ResizableControl"))
        {
            name = Assembly.GetAssembly(typeof(EntityLib.Pattern)).ToString();
        }
        else
        {
            name = assemblyName;
        }
        return Type.GetType(String.Format("{0}, {1}",
            typeName.Replace("ResizableControl", "EntityLib"), name));
    }
}

Спасибо, это именно то, что мне было нужно.

6 голосов
/ 23 августа 2011

Это присуще BinaryFormatter. есть некоторые продвинутые вещи, которые вы можете сделать, чтобы обойти это (с суррогатами и т. Д.), Но это нелегко, и я, честно говоря, не рекомендую это.

Я настоятельно предлагаю вам взглянуть на сериализатор на основе контракт ; например:

  • XmlSerializer
  • DataContractSerializer (но не NetDataContractSerializer)
  • Protobuf-сеть

(я склонен к последнему, поскольку он дает гораздо более эффективный вывод и намеренно избегает нескольких больше проблем с версиями)

Во всех этих случаях хранилище данных (по крайней мере, с настройками по умолчанию) не включает любое знание типов, за исключением контракта, подразумеваемого именами или как указано (обычно в атрибуты).

1 голос
/ 23 августа 2011

Я думаю, что это известная проблема с BinaryFormatter - здесь - это возможное решение Вы можете контролировать, какой тип загружать с помощью SerializationBinder - ссылка содержит код и пример, как его использовать (почти во всех языках .net)

...