Как сериализовать сторонний класс?

У меня есть служба WCF, которая использует стороннюю библиотеку. Библиотека не сериализуема.

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

MyClass.ThirdPartyClass

Проблема в том, что когда я отправляю MyClass из службы, ThirdPartyClass теряет значения, которые я присвоил ему во время службы. Поскольку у меня нет исходного кода для ThirdPartyClass, я могу пометить его как сериализуемый.

Есть ли способ пометить ThirdPartyClass как сериализуемый или какой-либо другой способ сохранить значения?


person 4thSpace    schedule 05.11.2013    source источник
comment
Вы должны иметь возможность использовать комбинацию Reflection и XmlTextWriter для перечисления общедоступных свойств и записи в XML. Я постараюсь собрать образец приложения позже сегодня вечером.   -  person Glenn Ferrie    schedule 06.11.2013
comment
Хм, хорошая идея. Может быть, есть что-то, что уже делает это? Не уверен, что вы будете искать под хотя.   -  person 4thSpace    schedule 06.11.2013
comment
google.com/   -  person Glenn Ferrie    schedule 06.11.2013
comment
Пожалуйста, скажите мне, что вы не пытаетесь сериализовать пользовательский интерфейс.   -  person Federico Berasategui    schedule 06.11.2013


Ответы (2)


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

Тогда у вас будет два свойства в вашем классе, одно строго для сериализации и одно для внутреннего использования.

Например, предположим, что сторонний класс выглядит так:

public class ThirdPartyClass
{
    public int Property1 { get; set; }
    public string Property2 { get; set; }
}

Вы можете создать такую ​​сериализуемую версию (при условии, что вы используете DataContracts):

[DataContract()]
public class ThirdPartyClassSerializable
{
    private ThirdPartyClass m_TPC = new ThirdPartyClass();

    public ThirdPartyClassSerializable();
    public ThirdPartyClassSerializable(ThirdPartyClass oTPC)
    {
        m_TPC = oTPC;
    }

    public ThirdPartyClass GetThirdPartyClass()
    {
        return m_TPC;
    }

    [DataMember()]
    public int Property1
    {
        get
        {
            return m_TPC.Property1;
        }
        set
        {
            m_TPC.Property1 = value;
        }
    }

    [DataMember()]
    public string Property2
    {
        get
        {
            return m_TPC.Property2;
        }
        set
        {
            m_TPC.Property2 = value;
        }
    }
}

Тогда ваш корневой сериализуемый класс будет выглядеть так:

[DataContract()]
public class MyClass
{
    private ThirdPartyClass m_ThirdPartyClass;

    public ThirdPartyClass ThirdPartyClass
    {
        get
        {
            return m_ThirdPartyClass;
        }
        set
        {
            m_ThirdPartyClass = value;
        }
    }

    [DataMember()]
    public ThirdPartyClassSerializable ThirdPartyClassSerialized
    {
        get
        {
            return new ThirdPartyClassSerializable(this.ThirdPartyClassNonSerialized);
        }
        set
        {
            this.ThirdPartyClass = value.GetThirdPartyClass();
        }
    }
}

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

Вторым преимуществом этого является то, что вы можете предоставлять столько стороннего класса, сколько вам нужно или нужно.

person competent_tech    schedule 05.11.2013

Я бы предложил создать объект передачи данных, содержащий данные, которые вы хотите предоставить через свой сервис. Вместо того, чтобы делать ThirdPartyClass частью MyClass, используйте новый DTO и сопоставьте данные ThirdPartyClass с DTO, прежде чем возвращать их из службы. Возможно, такая платформа, как AutoMapper, может помочь вам в этой задаче.
Хотя это требует дополнительных усилий, это также создает уровень абстракции между клиентами вашего сервиса и сторонней библиотекой. Это позволяет вам позже перейти на другую библиотеку, не изменяя интерфейс вашего сервиса.

person Markus    schedule 05.11.2013