XML-сериализация глубоко вложенных объектов подклассов

#c# #inheritance #xml-serialization

Вопрос:

У меня есть кодовая база, которая часто работает в страховой отрасли в формате XML. Спецификация ACORD очень велика, и она побуждает как пользователей, так и поставщиков определять свои собственные клиентские узлы, которые будут добавлены в спецификацию. Итак, для приведенного ниже XML-файла в его базовом состоянии

 <ACORD>
    <SignonRq>
        <SignonTransport></SignonTransport>
        <ClientApp>
            <Org></Org>
            <Name></Name>
            <Version></Version>
        </ClientApp>
    </SignonRq>
</ACORD>
 

Я могу сериализовать и десериализовать его в объекты C#, используя следующий код:

 ACORD acord;
using (var reader = new StringReader(xml))
{
    acord = (ACORD)serializer.Deserialize(reader);
}
return acord;

[XmlRoot(ElementName = "ACORD")]
public class ACORD
{
    [XmlElement(ElementName = "SignonRq")]
    public SignonRq SignonRq { get; set; }
    
    [XmlElement(ElementName = "InsuranceSvcRq")]
    public InsuranceSvcRq InsuranceSvcRq { get; set; }
}

[XmlRoot(ElementName = "SignonRq")]
public class SignonRq
{
    [XmlElement(ElementName = "SignonTransport")]
    public SignonTransport SignonTransport { get; set; }
    
    [XmlElement(ElementName = "ClientApp")]
    public ClientApp ClientApp { get; set; }
}

[XmlRoot(ElementName = "ClientApp")]
public class ClientApp
{
    [XmlElement(ElementName = "Org")]
    public string Org { get; set; }
    
    [XmlElement(ElementName = "Name")]
    public string Name { get; set; }
    
    [XmlElement(ElementName = "Version")]
    public string Version { get; set; }
}
 

Но как только поставщик или клиент решат, что им нужен свой собственный узел для конкретной компании в ClientApp под названием <com.mycompany_IsInteral><com.mycompany_IsInteral></com.mycopany_IsInteral>, шаблон распадается. Я могу легко подклассировать ClientApp в MyCompanyClientApp с помощью свойства IsInternal, но сериализатор проигнорирует новый узел и создаст базовое клиентское приложение при десериализации из XML, и просто предположит, что подкласс был базовым классом при сериализации. Я также мог бы подклассировать сам сериализатор, но не похоже, что переопределения обеспечивают необходимую степень детализации, если я чего-то не упускаю.

Я периодически ломаю голову, пытаясь определить, как я могу сохранить этот шаблон (и сохранить базовые классы в их отдельной многоразовой библиотеке DLL), но все же допускаю полиморфизм. Я часто отказывался и обновлял базовые классы в разных проектах, а в другом проекте я просто покончил с сериализатором и вручную проанализировал XML в его окончательном виде. Но эти решения не способствуют повторному использованию кода.

Я думал, что посмотрю, что думают большие мозги по этому поводу?

ТИА _Петер

Комментарии:

1. Пару лет назад я столкнулся с проблемой создания новых XML-структур для существующих классов. Я решил эту проблему с помощью шаблона посетителя, добавил новый метод GenerateSpecialXML в существующие классы с параметром (Посетитель v). Допустимо ли расширение ваших занятий?

2. В принципе, вы можете использовать шаблон расширения объекта и передавать ему свои классы через фабрику (если вы хотите, чтобы ваши классы оставались неприкосновенными).

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