сопоставить старые данные с новой структурой типа.

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

Пока что я перенес классы в новый проект. Я сохранил те же пространства имен, что и в старом проекте. Но этого было недостаточно для чтения объектов. Я получаю исключение SerializationException, в котором говорится "Ошибка разбора, тип не связан с ключом Xml a1 MyCorp.MyApp.DatabaseRoot MyCorp.MyApp". Глядя на сгенерированный SOAP XML, ссылки на схемы изменились. Например, у меня есть классMyCorp.Dashboard.DatabaseRoot изначально в проектеDashboardLibrary, Это было перенесено в проектDashboardData (но все еще используя пространство именMyCorp.Dashboard.DatabaseRoot). XML изменился следующим образом:

Orig: <a1:DatabaseRoot id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/MyCorp.Dashboard/MyCorp.Dashboard">
New:  <a1:DatabaseRoot id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/MyCorp.Dashboard/DashboardData">

Итак, мои вопросы

Можно ли перемещать классы и сохранять совместимость? Я, кажется, близок к тому, чтобы снять это.Если да, то как мне управлять информацией о последней битовой схеме (MyCorp.Dashboard vs. DashboardData). Кажется, что оригинал основан на расположении каталога, а второй - на имени проекта. Я пытался изменить структуру каталогов в новом проекте, но мне не повезло. Что-то еще я пропускаю?

Благодарю.

 Marc Gravell♦07 янв. 2011 г., 19:36
Какой сериализатор вы используете? Это ключ ...
 John Saunders07 янв. 2011 г., 21:26
Возможно, написать программу для чтения из старого источника и написать в новом формате?
 doobop08 янв. 2011 г., 00:12
Это было возможно, но я хотел что-то прозрачное для людей, управляющих этим.
 doobop07 янв. 2011 г., 20:39
System.Runtime.Serialization.Formatters.Soap.SoapFormatter

Ответы на вопрос(1)

Решение Вопроса

Вам нужно реализовать кастомSerializationBinder, ПереопределитьBindToType Метод выбора типа для загрузки на основе его имени:

public override Type BindToType(string assemblyName, string typeName)
{
    if (assemblyName == "MyOldAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
    {
        if (typeName == "MyOldNamespace.MyOldClass")
        {
            return typeof(MyNewClass);
        }
    }
    // Fall back to the default behavior, which will throw
    // a SerializationException if the old assembly can't be found
    return null;
}

(это очень простая реализация, в реальном сценарии вы, вероятно, использовали бы лучшую логику отображения).

Вы также можете переопределитьBindToName если вам нужно выполнить повторную сериализацию данных, чтобы они могли быть прочитаны старой сборкой. Это позволяет настроить сборку и имя типа сериализованного объекта.

Как только у вас есть свой обычайSerializationBinderвам просто нужно присвоить егоBinder свойство форматера, и используйте его обычно оттуда.

Если вам нужно изменить структуру типов (добавить или переименовать поля, изменить типы ...), вам необходимо реализоватьISerializationSurrogate сопоставить старые данные с новой структурой типа.

Ваш ответ на вопрос