2010-12-27 6 views
1

Okay, ich habe schon einige Fragen zu SO bezüglich Serialisierung gestellt, aber ich stecke immer noch fest - also denke ich, ich spucke nur meinen ganzen Fall aus, statt Subprobleme in der Hoffnung, dass jemand meine Nase in die Nase halten kann richtige Richtung :)Serialisieren eines Graphen mit bidirektionalen Links, (dll) importierten Typen und Versionierung ..?

Meine Anwendung ähnelt Apples "Quartz Composer", was bedeutet, ich habe eine baumartige Struktur von verbundenen Knoten.

Knoten werden durch eine INode-Schnittstelle definiert; Tatsächliche Knotentypen/Klassen werden aus DLLs mithilfe von MEF importiert, sodass Knotentypen zum Zeitpunkt der Kompilierung nicht bekannt sind.

Knoten sind verbunden, so dass bidirektionale Verbindungen auftreten können und werden.

Ich möchte meine "Zusammensetzung" - den gesamten Baum der Knoten - in eine Datei speichern, vorzugsweise lesbar wie XML. Ich möchte wirklich vermeiden, in einem proprietären Format zu speichern!

Also, was ich serialisiert werden muß, ist:

  • ein Baum von Objekten, der Klassen kann seine Laufzeit importiert (vorher und somit nicht bekannt), die bidirektionale Verbindungen enthalten kann.

  • Darüber hinaus möchte ich Versionsinformationen für die verwendeten Knotenklassen speichern, sodass es möglich ist, festzustellen, ob eine 'Komposition' mit einer älteren Version einer Knotenklasse als der verwendeten DLL/Knotenklasse gespeichert wurde in der aktuellen Anwendung.

Früher war ich an dem DataContractSerializer zeigt, die wie ein schickes Tool scheint meinen Baum zu speichern und in vollem Umfang die bidirektionale Verbindungen zu unterstützen.

Aber wenn ich will mein Baum (Interface IComposition) serialisiert werden, beginnt es über unbekannte Arten beschweren - ich jeden spezifischen Typ angeben müssen sie auftreten können, während der Baum Serialisierung ...

Und auch gibt es keine Möglichkeit für mich anzugeben, welche Assembly-Version für eine bestimmte Knotenklasse verwendet wurde.

Irgendwie fühlt es sich nicht richtig an, zuerst meinen gesamten Baum aufzulisten, um herauszufinden, welche Knoten-Klassen verwendet wurden, diese zu einer bekannten Typenliste hinzuzufügen und dann zu serialisieren.

Und selbst dann müsste ich eine Möglichkeit finden, einen Abschnitt zu den Ausgabedaten hinzuzufügen, die Versionsinformationen für verwendete Klassen angeben.

Vielleicht bin ich der Einzige mit diesem Problem, aber ich hoffe wirklich, dass jemand anderes dieses Problem schon früher angetroffen und überwunden hat - vorzugsweise mit einer eleganten Lösung;) Ich kann mir vorstellen, dass es sich nicht um einen Standard handelt .NET-Serializer, aber vielleicht gibt es eine Implementierung von Drittanbietern (kostenlos, Open Source sogar?)

+0

Übrigens, ich glaube, Sie meinten einen ".NET Serializer", kein "C# Serializer". –

+0

Entschuldigung, du hast recht :) – Pygmy

Antwort

0

Sie können dies mit oder SoapFormatter erreichen. Diese Formatierer arbeiten mit beliebigen Objektdiagrammen und behandeln beliebige Objekte, auf die sie stoßen (solange die Objekttypen mit [Serializable] markiert sind) und behalten zyklische Referenzen korrekt bei. Wenn Sie wissen möchten, wie die Objekte serialisiert werden, verwenden Sie SoapFormatter, das XML ausgeben wird.

Beachten Sie, dass alle Assemblys, die bei Bedarf geladen werden können, sich im GAC befinden müssen oder dass die Laufzeitumgebung sie nicht finden kann.

mit Versionierung umgehen, könnten Sie so etwas tun:

[Serializable] 
public class SomeVersionedClass : IDeserializationCallback 
{ 
    private const int CURRENT_VERSION = 10; 

    private int version = CURRENT_VERSION; 

    void IDeserializationCallback.OnDeserialization(object sender) 
    { 
     if (version != CURRENT_VERSION) 
      throw new ApplicationException(
       "Mismatch between serialized data version " + version + 
       " and required version " + CURRENT_VERSION + "."); 
    } 
} 

Beachten Sie, dass Sie vielleicht, statt Auslösen einer Ausnahme, Migration von Daten von einer früheren Version Layout auf die neue Version in Betracht ziehen. Bedenken Sie auch, dass das Entfernen von serialisierten Feldern aus einer Klasse die zukünftige Deserialisierung vollständig verhindert. Wenn Sie also die Migration von einem Feld entfernen möchten, das nicht mehr verwendet wird, müssen Sie dieses Feld beibehalten, damit frühere Versionen ordnungsgemäß deserialisiert werden können. und natürlich, damit Sie die Daten erhalten können, um sie zu migrieren).

+0

Danke für deine Antwort, aber kannst du mich auf irgendeine Seite verweisen, die mehr darüber erklärt, wie ich meine Bedürfnisse implementieren würde (bidirektionale Links, Klassenversionierung), die diese verwenden? Meine 5 Minuten Google Kung-Fu scheint zu schwach ... :) – Pygmy

+0

Bidirektionale und zyklische Links werden transparent von den Formatierer behandelt werden; Es gibt nichts, was Sie tun müssen, um sie zu bestehen. Ich werde meine Antwort aktualisieren, um einen Mechanismus für die Versionsverwaltung bereitzustellen. – cdhowie

Verwandte Themen