XmlSerializer и фабричные элементы - PullRequest
6 голосов
/ 21 ноября 2011

Я пытаюсь сериализовать / десериализовать объекты, которые имеют фабрично созданные элементы.Например, предположим, что есть член типа Foo, экземпляр которого создается с помощью FooFactory.CreateFoo (int bar).

Моя текущая идея -

1.создать пользовательский XmlReader(например, наследовать от XmlTextReader) и присоединить к нему фабрику

2.implement IXmlSerializable

3. в ReadXml (), я могу получить фабрику из читателя.

Не уверен, что это самый элегантный способ сделать это, кто-нибудь делал подобные попытки?

1 Ответ

6 голосов
/ 21 ноября 2011

XmlSerializer просто не настроен для этого. Я настоятельно рекомендую, чтобы, если вы хотите использовать XmlSerializer, лучше всего было бы сопоставить ваши данные с более простой моделью DTO first и сериализовать , что . При записи кода обратно из DTO в вашу модель добавьте фабричное создание туда в обычном коде. Модель DTO должна быть простой; достаточно просто для XmlSerializer чтобы быть счастливым.

Да, реализация IXmlSerializable является опцией , однако: этот API очень трудно получить на 100% правильно (чтобы справиться со всеми различными способами, которыми может казаться XML) , Я нахожу этот API очень сложным, и я делаю много сериализации. Я смиренно утверждаю, что написание нескольких строк кода для сопоставления вашей модели main с моделью DTO намного надежнее (и намного быстрее), чем попытка реализовать IXmlSerializable.

Например, вы могли бы иметь:

[XmlRoot("foo")]
public class FooDTO {
     [XmlAttribute("bar")]
     public int Bar {get;set;}

     public static implicit operator Foo(FooDTO value)
     {
         return value == null ? null : FooFactory.Create(value.Bar);
     }
     public static implicit operator FooDTO(Foo value)
     {
         return value == null ? null : new FooDTO { Bar = value.Bar; }
     }
}

затем вы можете конвертировать из Foo в FooDTO просто:

Foo foo = ...
FooDTO dto = foo;
...