2009-07-22 15 views
2

Gibt es einen robusten Mechanismus zum Erstellen einer Kopie des TRemotable-Objekts (oder Nachkommen) in Delphi 2007?Robuste Methode zum Erstellen einer Kopie eines TRemotable-Objekts in Delphi 2007

Ich erstelle einen Delphi Web-Service-Client, der eine Vielzahl von Objekten von einem Web-Service empfängt; Natürlich sind alle Nachkommen von TRemotable. Im Client erstelle ich ein passendes Objekt und kopiere dann alle Eigenschaften aus dem Webservice, der TRemotable zur Verfügung stellt, auf mein eigenes Objekt. Dies geschieht über TypInfo.GetPropList() und dann eine Schleife um TypInfo. Methodenaufrufe GetPropValue() und TypInfo.SetPropValue(). Obwohl dies für die einfachen Typen - Strings, Ints, Bool usw. - hervorragend geeignet ist, funktioniert es nicht für komplexe Typen wie Daten, Zeiten oder Unterobjekttypen. Und ich nehme an, dass, wenn der Web-Service jemals einen neuen komplexen Typ verwendet, mein Kopiercode auch brechen würde.

Es scheint eine Möglichkeit zu sein, das Objekt in ein XML-Dokument zu serialisieren und es dann in das neue Objekt einzulesen. Aber das scheint eine Menge Aufwand zu sein, um eine Reihe von Eigenschaften zu kopieren.

Antwort

2

Gefunden eine robustere Lösung, scheint einfach Typen, TXS ... Derivat-Typen und subobject Arten zu funktionieren:

procedure CopyNormal(Source, Target: TRemotable); 
var 
    Converter: IObjConverter; 
    NodeObject: IXMLNode; 
    NodeParent: IXMLNode; 
    NodeRoot: IXMLNode; 
    XML: IXMLDocument; 
    XMLStr: WideString; 
begin 
    XML:= NewXMLDocument; 
    NodeRoot:= XML.AddChild('Root'); 
    NodeParent:= NodeRoot.AddChild('Parent'); 
    Converter:= TSOAPDomConv.Create(NIL); 
    NodeObject:= Source.ObjectToSOAP(NodeRoot, NodeParent, Converter, 'CopyObject', '', [ocoDontPrefixNode], XMLStr); 
    Target.SOAPToObject(NodeRoot, NodeObject, Converter); 
end; 
+0

für spätere Versionen (mindestens XE7) ändern, um NodeObject zu sagen: = Source.ObjectToSOAP (NodeRoot, NodeParent, Konverter, 'CopyObject', '', '', [ocoDontPrefixNode], XMLStr); – skamradt

0

TDateTime ist nur ein Double mit einem anderen Namen, und Sie sollten in der Lage sein, es ohne Probleme zu kopieren. Oder verwenden Sie ein anderes Format für Ihre Daten und Uhrzeiten?

Wie für Unterobjekte können sie behandelt werden, indem Sie Ihre Kopierroutine rekursiv machen. Wenn es auf eine Eigenschaft trifft, die ein Objekt ist, muss es eine Kopie dieses Objekts erstellen und es dem übergeordneten Objekt zuweisen. (Hinweis: Dies funktioniert nur, wenn das Unterobjekt auch Eigenschaften veröffentlicht hat.)

+0

TDateTime ist ein Double in nativem Delphi-Code. Aber nicht, wenn es eine TRemotable-Eigenschaft ist; In diesem Fall ist es eine TXSDateTime. Es sieht so aus, als ob mein Kopiercode bei einem der TXS ... Typen bricht. –

0

Ja, Sie könnten die Kopie rekursiv machen, aber das lässt Sie immer noch mit Problemen, wie Sie interne private Felder kopieren. Sie müssten alle Felder als Eigenschaften aufdecken und meiner Meinung nach ist das nicht sauber und umständlich.

Ich würde auf jeden Fall das Objekt serialisieren. SOAP hat so viel Overhead, dass die Serialisierung im Vergleich dazu superschnell ist. Ich würde sogar argumentieren, dass ein einfacher HTTP-Ansatz mit REST besser wäre.

Sie können mein SimpleStorage-Framework betrachten, das mit solchen Aufgaben (Serialisierung) gemacht wurde. Schauen Sie sich speziell die Adapter-Funktion an.

Sie können es abrufen: http://www.cromis.net/blog/downloads/

Es gibt dort auch Artikel, die zeigen, wie es zu benutzen. Wenn Sie bereits eine andere XML-Bibliothek verwenden und nicht wechseln möchten, würde ich immer noch den Serialisierungsansatz bevorzugen, wenn ich Sie wäre.

Ich bezweifle, dass Sie eine HTTP-Anfrage unter 30 ms dauern können. Die Serialisierung würde viel weniger in Anspruch nehmen. Jetzt den SOAP-Aufwand hinzufügen und Sie sind super schnell im Vergleich zu it :)

+0

Ich mache mir keine Sorgen um private Immobilien. Diese TRemotable-Nachkommenobjekte werden von WSDLImp.exe erstellt und haben nur veröffentlichte Eigenschaften. Und wenn ich meine eigenen Nachkommen dieser Objekte mit meinen eigenen privaten Eigenschaften erstelle, wären die einzigen Eigenschaften, die ich kopieren möchte, die ursprünglich veröffentlichten. –

+0

Der HTTP + REST-Ansatz funktioniert auch nicht; Die Webservices liegen außerhalb meiner Kontrolle und SOAP ist der einzige Ansatz. –

+0

Ok, ich sehe, Sie haben eine Lösung gefunden, die für Sie arbeitet.Ich wusste nicht, dass SOAP obligatorisch war – Runner

Verwandte Themen