2009-10-03 7 views
6

Après avoir lu Data Contract Versioning, nous avons conclu que ce n'est pas vraiment toute l'histoire. Par exemple, que se passe-t-il si vous avez eu ValueA, et dans la nouvelle version il s'appelle maintenant ValueB et est d'un type différent, et vous devez convertir ValueA en ValueB?Version simple du fichier de données avec DataContractSerializer

Il y a quelques callbacks que je pourrais utiliser pour vous aider, mais cela ne semble pas être une solution très facile à maintenir si nous nous attendons à ce que le format change fréquemment sur une longue période de temps.

La solution pour laquelle nous nous sommes contentés est de conserver un champ "sauvegardé par version", et lors du chargement du fichier, invoquer des routines de conversion spécifiques aux anciennes versions, si nécessaire. Ces routines de conversion savent comment convertir du XML pour des données plus anciennes en XML pour des données plus récentes.

Cependant, il s'avère, DataContractSerializes requires the order of the elements to be exactly what it expects. Cela signifie que notre processus de conversion doit savoir insérer des éléments dans exactement l'emplacement correct. C'est beaucoup plus difficile que d'ajouter simplement un élément avec un nom connu, si vous tenez compte de l'héritage. Avec l'héritage, vous ne pouvez pas utiliser de manière fiable un champ , simplement parce qu'il n'y a pas un seul champ qui soit toujours à côté de ce nouveau champ.

Laissant de côté les raisons pour lesquelles DataContractSerializer a été rendu si strict, pouvez-vous suggérer des façons de contourner cela? Peut-être un bon article sur la façon de rester rétrocompatible avec des contrats de données très anciens, cela ne devient pas compliqué au moment où vous avez fait le 100e changement de format.

Il y a quelques directives supplémentaires dans this article, mais cela doit avoir été écrit dans un but différent. Il n'y a par exemple aucun moyen de laisser les anciens membres des données traîner pour toujours (point 9). Il semble que la plupart de ces articles sont écrits du point de vue du protocole de communication, plutôt que de stocker des données dans un fichier.

Répondre

2

Je pense que vous attendez trop de la prise en charge de la gestion des versions intégrée. Il est vraiment destiné à vous permettre d'ajouter de nouveaux membres tout en conservant toutes les fonctionnalités existantes et donc les membres. En cas de rupture de contrat, vous feriez probablement mieux de créer une nouvelle version du contrat (par exemple en utilisant un nouvel espace de noms - une convention commune est d'utiliser un suffixe aaaa/mm, par exemple http://mycompany.com/myservices/2009/10).

Vous devez ensuite être en mesure de prendre en charge autant de vieux contrats que nécessaire, et devez pouvoir convertir entre chaque contrat pris en charge et la représentation interne actuelle que vous utilisez.

+0

C'est un contrat assez important; Je détesterais vraiment copier et coller la plupart d'entre eux juste pour changer un booléen "Enabled" en un "State" enum par exemple. Je vais m'en tenir au pré-traitement XML, qui, malgré les problèmes décrits dans la question, est assez facile à mettre en œuvre. –

4

1 an plus tard, je dois dire que DataContractSerializer a vraiment aspiré pour le versionnage. C'est trop rigide. C'est vraiment destiné aux contrats qui ne sont pas très susceptibles de changer, et seulement de façon spécifique. Vous devez faire un travail supplémentaire pour l'utiliser juste pour le rendre rapide - comme le KnownTypeAttribute par exemple. Je ne le recommanderais que si vous avez besoin d'une sérialisation relativement rapide - ce qui, sans doute, est plutôt important pour ce pour quoi il a été conçu. Un autre projet sur lequel je travaille utilise un sérialiseur plus flexible qui, par exemple, n'ignore pas appeler le constructeur de classe (quelque chose a causé beaucoup d'inconvénients), et ne nécessite pas d'éléments dans un ordre spécifique. Il traite gracieusement de nouveaux champs (ils sont laissés à tout ce que le constructeur leur a assigné) et supprime les champs sans intervention du programmeur.

Maintenant, si seulement je pouvais l'afficher ici ... Il est cependant environ 5x-10x plus lent que le DataContractSerializer.

+0

Tout d'abord merci d'avoir fait ce post, j'étais sur le point de se lancer dans le même cauchemar que vous avez traversé au cours de la dernière année. Je n'arrive pas à trouver une bonne alternative à DataContractSerializer, je suppose que votre autre Serializer est propriétaire, donc vous ne pouvez pas le partager? – Jambobond

+0

@Jambobond J'ai tellement peur :( –

Questions connexes