4 Stimmen

Wie funktionieren virtuelle Proxys?

Ich habe einige Schwierigkeiten, virtuelle Proxys zu verstehen. Ich habe tonnenweise Artikel gelesen und mehrere Stunden damit verbracht, gute Informationen zu finden, aber ich habe noch nichts Umfassendes gefunden. Daher werde ich hier eine allgemeine Anfrage nach besseren Informationen stellen (entweder hier veröffentlicht oder einfach ein Link). Ich werde auch einige Details unten hinzufügen, um besser zu erklären, was genau es ist, ich will.

Ich habe mehrere Objekte und es gibt viele Verweise zwischen ihnen. Der Einfachheit halber werde ich ein Objekt (Node) mit einer einfachen Eltern-Kind-Beziehung verwenden. Wenn ich dieses Objekt aus der Datenbank ziehe, möchte ich Lazy-Loading implementieren. Nach dem, was ich gelesen habe, wird ein virtueller Proxy im Wesentlichen das gesamte Lazy-Loading für mich übernehmen, indem er die Schnittstelle (INode) referenziert und Datenelemente nach Bedarf abruft. (Hinweis: Ich habe nicht tatsächlich eine INode-Klasse, aber wenn ich das virtuelle Schlüsselwort auf meine Datenmitglieder setzen, ein Proxy schien verwendet werden]

Wenn ich Datenelemente in meinen Klassen virtuell mache, scheint es einen Proxy zu erstellen. Ist dies ein virtueller Proxy? Implementieren diese das "Lazy-Loading"?

Ich suchte nach Informationen über das virtuelle Schlüsselwort, aber die einzige Dokumentation, die ich finden konnte, war es auf Methoden zu verwenden, die für die Vererbung verwendet wird, so dass abgeleitete Klassen die Funktion überschreiben können, die nichts zu tun hat mit dem, was ich will (ich denke).

Dies ist meine aktuelle Node.cs

[DataContract(IsReference=true)]
public partial class Node
{
  [DataMember]
  public long ID { get; private set; }
  [DataMember]
  public virtual Node Parent { get; set; }
  [DataMember]
  public virtual ICollection<Node> Children { get; set; }
}

Im Grunde genommen bin ich an diesem Punkt sehr verwirrt und brauche einfach eine Anleitung zu diesem Thema oder sogar eine Online-Ressource, die ich suchen kann, da alle, die ich gefunden habe, weniger als hilfreich waren.

Vielen Dank im Voraus.

5voto

Ladislav Mrnka Punkte 355028

Ein "virtueller" Proxy und "Lazy Loading" sind etwas, das mit ORM-Tools zusammenhängt. Der Proxy ist eigentlich nicht virtuell, sondern dynamisch und folgt dem echten Proxy-Muster, das durch die GoF definiert ist.

Das dynamische Proxy ist eine Klasse, die vom ORM-Tool zur Laufzeit erstellt wird (es ist nirgendwo als Codedatei definiert). Er leitet sich von Ihrer Entität ab und überschreibt die Navigationseigenschaften. Aus diesem Grund müssen sie virtuell sein, damit ein Proxy funktioniert. Der Proxy speichert den Zustand der Navigationseigenschaft in einem privaten Feld oder einer komplexeren Struktur. Wenn auf die Eigenschaft zum ersten Mal zugegriffen wird, stellt er fest, dass der Zustand entladen ist, löst das Laden aus der Datenbank aus und ändert den Zustand in geladen.

Jedenfalls bin ich nicht sicher, wie dies bezieht sich auf WCF, weil beste Praxis nicht mit Lazy Loading mit WCF ist. Warum?

  • Wenn Sie Lazy Loading auf der Serverseite verwenden, wird die Serialisierung immer den gesamten Objektgraphen aus der Datenbank abrufen, da die Serialisierung auf jede Navigationseigenschaft zugreift und Lazy Loading auslöst, aber dann beginnt sie mit der Serialisierung von Lazy Loaded Entities und greift auf alle Navigationseigenschaften usw. zu.
  • Das faule Laden auf der Client-Seite ist etwas Unschönes. Zunächst einmal ist das faule Laden auf der Client-Seite völlig Ihnen überlassen - Sie müssen es implementieren. Bei der Verwendung von Diensten sollten Sie immer einen der SOA-Grundsätze befolgen: Die Service-Grenze ist explizit. Das bedeutet, dass der Benutzer Ihres Objekts immer wissen sollte, dass er einen Fernaufruf statt eines lokalen Aufrufs tätigt. Das Hauptziel bei der verteilten Datenverarbeitung ist die Verringerung von Netzwerktransfers. Daher sollten Sie eager loading verwenden und alle benötigten Daten nach Möglichkeit in einem einzigen Roundtrip übertragen, anstatt sie zeitversetzt zu laden. Dasselbe gilt für das Laden aus der Datenbank - verwenden Sie "Lazy Loading", wenn es sinnvoll ist, da Roundrips zur Datenbank kostspielige Operationen sein können.

1voto

Ricibob Punkte 7297

Ich denke, Sie wollen einige private Felder, die Ihre virtuellen Grundstücke unterstützen. In den Get-Overrides dieser virtuellen Eigenschaften überprüfen Sie das private Feld, um zu sehen, ob es aktuell gültig ist (wurde es bereits aus der Datenbank geholt, ist es aktuell usw.) - wenn nicht, dann holen Sie es oder holen Sie es erneut. Ich sehe nicht, dass es noch komplizierter sein muss als das.

Basisklasse:

private Node _Parent;
public virtual Node Parent { 
    get { return _Parent; } // Default no lazy fetch.
}

Überschreiben:

public override Node Parent {
    get {
        if (_Parent==null) // or out of date, dirty etc
            Do_db_get_of_parent();
        return _Parent;
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X