Два набора атрибутов сериализации в одном классе - PullRequest
3 голосов
/ 17 марта 2011

Я столкнулся с проблемой дизайна класса.

Я использую сериализатор контракта данных.

Итак, в сборке, которая является общей для всех моих приложений, у меня есть что-то вроде этого:

// Assembly DataContracts.dll: .NET 3.0, used by every subsystems
[DataContract]
public class User
{
    /// <summary>Nickname.</summary>
    [DataMember]
    public string displayName;
}

Есть еще много полей: я оставил только displayName, пытаясь сжать мои списки кодов.

Однако одно из приложений - это сервер, которому требуется другой сериализатор для применения к тому же классу следующим образом:

// Assembly ServerDatabase.dll, .NET 4.0, used only by server.
[EseTable]
public class User
{
    /// <summary>Nickname.</summary>
    [EseText(bUnicode=true, maxChars=71)]
    public string displayName;
}

ServerDatabase.dll связан с .NET 4. Более того, атрибуты [Ese *] определены в DLL, которая может быть загружена только серверным компонентом по независящим от меня причинам, поэтому я не могу просто иметь один класс с обоими наборами атрибутов, общими для каждой подсистемы.

В настоящее время я написал что-то вроде этого:

// DataContracts.dll
[DataContract]
public class User
{
    [DataMember]
    public string displayName;
}

// ServerDatabase.dll
[EseTable]
public class UserRecord: User
{
    [EseText(bUnicode=true, maxChars=71)]
    new public string displayName { get { return base.displayName; } set { base.displayName=value; } }

    // Note I need to implement an upcasting copy constructor, to convert from User to UserRecord :-(
    public UserRecord(User that)
    {
        base.displayName=that.displayName;
    }
}

Мне не очень нравится мое решение: похоже на взлом и подвержено ошибкам. Любые другие лучшие идеи, исправления или исправления?

Заранее спасибо!

1 Ответ

0 голосов
/ 17 марта 2011

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

Лично ясоздаст слой DTO для «необычного» уровня и отобразит между ними.Очень похоже на пример в вопросе, возможно, с использованием AutoMapper.Другой вариант - посмотреть, поддерживает ли другой сериализатор метаданные из источников, отличных от атрибутов.Некоторые делают, а некоторые нет.

Если с помощью автоматического средства возникают проблемы, вы можете просто аннотировать DTO своего сервера с теми же атрибутами DCS и использовать DCS для перевода модели, то есть

[EseTable, DataContract]
public class User
{
    /// <summary>Nickname.</summary>
    [EseText(bUnicode=true, maxChars=71), DataMember]
    public string displayName;
}

AsПока имена совпадают, DCS должен быть достаточно доволен этим.то есть использовать DCS для сериализации из одной модели и десериализации как модель другая .Я использую подобные трюки в нескольких местах (хотя я использую для этого собственный сериализатор, а не DCS - быстрее; p)

...