Domanda

Un progetto a cui sto lavorando richiede la serializzazione di una struttura di dati prima di chiudere e ripristinare il suo stato da questi dati serializzati quando si riavvia.

L'anno scorso, stavamo costruendo per .NET 1.1 e ci siamo imbattuti in un problema complicato in cui

  • il nostro codice è stato eseguito su .NET 2.0
  • un cliente aggiornato con alcuni software che in qualche modo ha impostato 1.1 come predefinito
  • il nostro codice è stato eseguito su .NET 1.1 e non è stato in grado di deserializzare il suo stato archiviato

Questo particolare problema era " risolto " impedendo quel particolare aggiornamento del software, e non dovrebbe essere un problema ora che stiamo prendendo di mira il framework .NET 2.0 (quindi non possiamo eseguire su 1.1).

Qual è la possibilità che questa serializzazione possa cambiare di nuovo in modo incompatibile tra framework 2.0 e più recenti? Se utilizziamo <supportedVersion> per correggere il nostro codice su 2.0.50727, quali sono le possibilità di modifiche tra 2.0.50727.1434 e 2.0.50727.nnnn (alcune versioni future)? Le strutture di dati che vengono serializzate sono array, mappe, stringhe, eccetera dalle librerie di classi standard.

Inoltre, è garantito che un framework 2.0.50727 sarà sempre installato anche dopo ulteriori aggiornamenti .NET? Puntatori alla documentazione di Microsoft benvenuti.

È stato utile?

Soluzione

Le possibilità sono basse (ma non zero!) che ci saranno cambiamenti tra le versioni del framework. L'intenzione sarebbe quella di essere in grado di utilizzare la serializzazione binaria e il remoting per comunicare tra un client e un server che eseguono versioni di framework diverse. L'incompatibilità tra .NET 1.xe 2.0 è un bug per cui è disponibile una patch.

Tuttavia la serializzazione binaria presenta altri problemi, in particolare uno scarso supporto per il controllo delle versioni della struttura che stai serializzando. Dal caso d'uso che hai descritto, la serializzazione Xml è la scelta ovvia: DataContractSerializer è più flessibile di XmlSerializer se non ti dispiace la dipendenza da .NET 3.x.

Non puoi garantire che .NET framework 2.0 sarà sempre installato su versioni future di Windows. Ma sono sicuro che Microsoft lavorerà sodo per garantire che la maggior parte delle app .NET 2.0 funzioneranno invariate su .NET 4.xe versioni successive. Non ho riferimenti per questo: un tale impegno si applicherebbe in ogni caso solo alla prossima versione di Windows (Windows 7).

Altri suggerimenti

La regola empirica è in genere: la serializzazione XML dovrebbe essere in grado di sopravvivere a nuove versioni di framework e quindi può essere archiviata a lungo termine, ma la serializzazione binaria non può (e quindi dovrebbe essere solo temporanea).

Quale serializzatore stai usando? In molti modi, un serializzatore come XmlSerializer o DataContractSerializer ti protegge da molti dettagli e fornisce opzioni di estensibilità più semplici. Ad un certo punto, sarà senza dubbio necessaria una nuova versione di CLR, quindi non credo che nessuno possa offrire alcuna garanzia sulla 2.0.50727; dovresti essere sicuro a breve termine, comunque. E vorrei sperare in meno cambiamenti di rottura ...

[aggiornato in seguito alla nota su un'altra risposta]

Se si desidera un formato binario per motivi di spazio / prestazioni, un'altra opzione è quella di utilizzare un serializzatore binario diverso. Ad esempio, protobuf-net funziona su tutte le varianti di .NET *, ma il binario formato (ideato da Google) è compatibile multipiattaforma (Java, C ++, ecc.), rendendolo molto portatile, veloce e piccolo.

* = Non l'ho provato su micro framework, ma CF, Silverlight, Mono, .NET 2.0 ecc sono tutti supportati.

Se la compatibilità è un problema, ISerializable interfaccia potrebbe essere la cura che stai cercando. Questa interfaccia offre un maggiore controllo su come gli articoli sono serializzati. Per ulteriori informazioni, prova questo articolo su msdn .

Ho due cose da aggiungere alle altre risposte ...

Innanzitutto, utilizzando un SerializationBinder può farti superare molte difficoltà nell'importazione di dati serializzati legacy.

In secondo luogo, ritengo obbligatorio scrivere approfonditi test unitari per eventuali dati persistenti. Faccio sempre due test in particolare:

  1. Test di andata e ritorno: puoi serializzare e deserializzare i tuoi oggetti e riavere esattamente la stessa cosa?
  2. Test di importazione legacy: assicurati di esportare versioni di dati serializzati da ogni versione rilasciata della tua app. Importa i dati e verifica che tutto ritorni come previsto.

Non è necessario utilizzare XML per ottenere maggiore flessibilità e controllo delle versioni.

Ho usato la libreria open source di Simon Hewitt, vedi Ottimizzazione della serializzazione in .NET - parte 2 invece della serializzazione .NET predefinita. Offre un po 'di automazione, ma essenzialmente puoi controllare il flusso di informazioni serializzate e deserializzate. Per il controllo delle versioni, la versione (file) può essere serializzata prima e su il tempo di deserializzazione nel modo in cui viene interpretato il flusso di informazioni dipende dalla versione.

È abbastanza semplice da fare, anche se un po 'noioso a causa dell'esplicito serializzazione / deserializzazione.

Come bonus è 20-40 volte più veloce e occupa meno spazio per grandi set di dati (ma potrebbe non essere importante nel tuo caso).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top