Каков практический способ сериализации экземпляра подкласса с использованием DataContractSerializer? - PullRequest
3 голосов
/ 13 июня 2011

Каков практический способ сериализации экземпляра подкласса с использованием DataContractSerializer?

Например, вот типы данных:

 [DataContract]
    public class Car
    {
        public Car()
        {
            Wheels = new Collection<Wheel>();
        }

        [DataMember]
        public Collection<Wheel> Wheels { get; set; }
    }

    [DataContract]    
    public abstract class Wheel
    {
        [DataMember]
        public string Name { get; set; }
    }

    [DataContract]
    public class MichelinWheel : Wheel
    {
        [DataMember]
        public string Wheel1Test { get; set; }
    }

    [DataContract]
    public class BridgeStoneWheel : Wheel
    {
        [DataMember]
        public string Wheel2Test { get; set; }
    }

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

    Car car = new Car();

    MichelinWheel w1 = new MichelinWheel { Name = "o1", Wheel1Test = "o1 test" };
    BridgeStoneWheel w2 = new BridgeStoneWheel { Name = "o2", Wheel2Test = "o2 test" };

    car.Wheels.Add(w1);
    car.Wheels.Add(w2);

Теперь, если я попытаюсь сериализовать автомобиль с помощью DataContractSerializer, я получу исключение, которое говорит, что MichelinWheel не ожидается. И я должен изменить класс Wheel следующим образом, чтобы он работал:

 [DataContract]
    [KnownType(typeof(MichelinWheel))]
    [KnownType(typeof(BridgeStoneWheel))]
    public abstract class Wheel
    {
        [DataMember]
        public string Name { get; set; }
    }

Но этот подход не практичен, потому что я не могу перечислить все виды колес до их создания. И менять класс Wheel каждый раз после создания новой марки колеса также нецелесообразно, поскольку они могут быть созданы в стороннем коде.

Итак, каков практический подход к сериализации экземпляра подкласса при использовании DataContractSerializer?

Спасибо

Ответы [ 2 ]

4 голосов
/ 13 июня 2011

Отметьте эту статью , используя DataContractResolver из WCF 4. Вы также можете использовать KnownTypeAttribute с , передавая имя метода , который будет использовать отражение для получения всех типов. В любом случае служба требует, чтобы все типы были известны до ее запуска.

1 голос
/ 13 июня 2011

Существует несколько способов сделать известные типы доступными для службы.

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

Вы также можете настроить KnownTypes:

...