Sto usando Delphi XE2 per comunicare con un servizio SOAP abbastanza grande. Ho importato con successo wsdl e tutto funziona perfettamente. Tuttavia, mi trovo a scrivere un sacco di codice simile. Mi piacerebbe avere un metodo generico che chiama il mio servizio web. Trovo anche difficile multithread il mio codice come è ora, dal momento che devo scrivere così tanto codice per ogni tipo di chiamata.Richiamare dinamicamente un metodo SOAP per nome?
Essendo più un programmatore del fine settimana, sono lontano dal padroneggiare i dettagli di Delphi, ma penso di avere almeno una buona comprensione di RTTI, che credo debba essere usato per fare ciò che voglio.
Il servizio Web ha circa 700 metodi diversi e questo è praticamente il problema. Il codice generato dal WSDL ha metodi come di seguito:
function addPhone(const Params: addPhone): addPhoneResponse; stdcall;
function updatePhone(const Params: updatePhone): updatePhoneResponse; stdcall;
function getPhone(const Params: getPhone): getPhoneResponse; stdcall;
function removePhone(const Params: removePhone): removePhoneResponse; stdcall;
function listPhone(const Params: listPhone): listPhoneResponse; stdcall;
function addStuff(const Params: addStuff): addStuffResponse; stdcall;
function updateStuff(const Params: updateStuff): updateStuffResponse; stdcall;
...
... about 700 more of the above
In sostanza, non v'è di circa 700 diversi tipi di cose che può essere gestito, e non v'è aggiungere, aggiornare, ottenere, rimuovere e list-metodi per tutti loro . Con ogni chiamata, esiste una classe corrispondente che viene utilizzata come parametri per la richiesta SOAP. C'è anche una classe corrispondente per la risposta, come puoi vedere sopra.
Le classi dovrebbero essere simile (molto semplificata):
addStuff = class
private
FStuff: string;
published
property stuff: string Index (IS_UNQL) read FStuff write FStuff;
end;
Così, quando io chiamo il servizio web che faccio, per esempio:
procedure CreateStuff;
var
req: addStuff;
res: addStuffResponse;
soap: MyWebServicePort;
begin
// Use the function in the wsdl-generated code to create HTTPRIO
soap := GetMyWebServicePort(false,'',nil);
// Create Parameter Object
req := addPhone.Create;
req.stuff := 'test';
// Send the SOAP Request
res := soap.addStuff(req);
end;
(Sì, lo so che avrei dovuto provare ..finally e Free in là pure :-))
Quindi, da qualche altra parte nel codice ho bisogno di chiamare un metodo diverso:
Poiché so che il parametro è sempre una classe con un nome equivalente al metodo che chiamo, mi piacerebbe essere in grado di fare qualcosa come il metacode di seguito per richiamare dinamicamente la chiamata. Credo che richiede un po 'di magia RTTI ma have'nt stato in grado di trovare un modo per farlo:
procedure soapRequest(Param: Something; var Response: Something);
begin
soap := GetMyWebServicePort(false,'',nil);
Response := soap.DynamicInvoke(Param.ClassName, Param);
end
allora avrei potuto fare qualcosa di simile:
soapRequest(VarOfTypeAddStuff,VarOfTypeAddStuffResponse)
soapRequest(VarOfTypeListStuff,VarOfTypeListStuffResponse)
...
Qualcuno ha un'idea di come il mio le chiamate al webservice possono essere semplificate?
sarà interessante per vedere se qualcuno si presenta con tali, ma ho appena scritto le routine di wrapper come si deve "nascondere" i dettagli. – mj2008
@dahook: il primo post scritto molto bene. Votato. Benvenuti in SO. – RobertFrank