2013-03-26 29 views
11

Jeśli chcę serializować obiekt, muszę użyć atrybutu [Serializable], a wszystkie zmienne składowe zostaną zapisane w pliku. Czego nie wiem, jak wykonywać wersjonowanie, np. jeśli dodaję nową zmienną składową (zmieniam nazwę zmiennej lub po prostu usuwam zmienną), a następnie otwieram (deserializuję) plik, w jaki sposób mogę określić wersję obiektu/pliku, aby poprawnie ustawić nowego członka lub przeprowadzić migrację? Jak ustalić, czy zmienna została zainicjowana podczas ładowania, czy nie (ignorowana przez deserializer).Serializacja i wersjonowanie obiektów w C#

Wiem, że istnieją podejścia tolerancyjne dla wersji i mogę oznaczyć zmienne atrybutem [OptionalField(VersionAdded = 1)]. Jeśli otworzę stary plik, framework zignoruje tę opcjonalną (nową zmienną) i będzie to zero/zero. Ale znowu, jak mogę określić, czy zmienna jest inicjowana przez obciążenie, czy została zignorowana.

Mogę wpisać numer wersji klasy/obiektu do strumienia. Użyj metody ISerializable iw metodzie constructor(SerializationInfo oInfo, StreamingContext context) odczytaj numer wersji. To dokładnie powie mi, jaka jest wersja klasy w strumieniu.

Jednak spodziewałem się, że taka wersja jest już zaimplementowana przez framework strumieniowania w języku C#. Próbowałem uzyskać wersję Assembly z wersji SerializationInfo, ale zawsze jest ona ustawiona na aktualną wersję, a nie wersję używaną przy zapisywaniu obiektu.

Jakie jest preferowane podejście? Znalazłem wiele artykułów w internecie, ale nie mogłem znaleźć dobre rozwiązanie dla tego, który rozwiązuje wersjonowanie ...

Każda pomoc jest mile widziana Dzięki, Abyss

Odpowiedz

2

Wybacz mi, jeśli część tego, co ja pisać jest zbyt oczywiste,

Po pierwsze, proszę! musisz przestać myśleć, że serializujesz obiekt ... To jest po prostu niepoprawne, ponieważ metody, które są częścią twojego obiektu, nie są utrzymywane. Masz trwałe informacje - a więc ... tylko dane.

. Seralizacja serializująca .NET serializująca nazwę typu obiektu, która zawiera nazwę zespołu i jego wersję, więc podczas deserializacji - porównuje utrwalone informacje o złożeniu z typem, który zostanie zamanifestowany z informacją - jeśli nie są to samo zwróci wyjątek.

Oprócz problemu z wersjami - nie wszystko można tak łatwo serializować. Spróbuj serializować typ System.Drawing.Color i zaczniesz rozumieć problemy z nadmiernie uproszczonym mechanizmem serializacji .NET.

Jeśli nie planujesz serializować czegoś naprawdę prostego, który nie ma planów ewoluowania, nie użyłbym mechanizmu serializacji dostarczonego przez .NET.

Skupiając się ponownie na swoim pytaniu, możesz przeczytać tutaj o zdolności ignorowania wersjonowania: http://msdn.microsoft.com/en-us/library/ms229752(v=vs.80).aspx, która jest przewidziana dla BinaryFormatter.

Powinieneś również sprawdzić Serializację XML, która ma pewne miłe zdolności, ale największą korzyścią jest to, że otrzymujesz XML, który jest czytelny dla człowieka, więc Twoje dane nigdy nie zostaną utracone, nawet jeśli masz komplikacje związane z wersją typów.

Ale w końcu, polecam albo użyć bazy danych z Entity Framework, aby utrwalić swoje dane, albo napisać własny płaski menedżer plików.podczas gdy EF jest bardzo dobre dla większości rozwiązań, czasami możesz chcieć czegoś lżejszego, aby utrzymać coś bardzo prostego. (Moja sugestia jest taka, że ​​nie widzę już rozwiązania, w którym może występować serializacja .NET).

Mam nadzieję, że to pomoże, powodzenia.

+1

+1 za sugerowanie zastosowania podejścia innego niż serializacja .NET. – Theraot