2012-06-28 11 views
14

मैं डेल्फी एक्सई 2 का उपयोग काफी बड़ी एसओएपी सेवा के साथ संवाद करने के लिए कर रहा हूं। मैंने सफलतापूर्वक wsdl आयात किया है और सब कुछ ठीक काम कर रहा है। हालांकि, मैं खुद को बहुत सारे कोड लिख रहा हूं। मैं एक सामान्य विधि चाहता हूं जो मेरी वेब सेवा को कॉल करे। मुझे अपने कोड को मल्टीथ्रेड करना भी मुश्किल लगता है क्योंकि अब यह है, क्योंकि मुझे प्रत्येक प्रकार के कॉल के लिए इतना कोड लिखना है।गति से एक एसओएपी विधि को गतिशील रूप से आमंत्रित करना?

सप्ताहांत प्रोग्रामर के अधिक होने के नाते मैं डेल्फी के अंदर और बाहर महारत हासिल करने से बहुत दूर हूं, लेकिन मुझे लगता है कि मुझे कम से कम आरटीटीआई की उचित समझ है, जो मुझे विश्वास है कि मुझे जो चाहिए वह करने के लिए इस्तेमाल किया जाना चाहिए।

वेब सेवा में लगभग 700 विभिन्न विधियां हैं और यह काफी समस्या है। wsdl से उत्पन्न कोड के रूप में नीचे दी गई विधियों है:

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 

मूल रूप से, वहाँ चीजों की लगभग 700 विभिन्न प्रकार है कि नियंत्रित किया जा सकता है, और वहाँ है जोड़ने, अपडेट मिलता है, हटाने और सूची-तरीकों उन सब के लिए । प्रत्येक कॉल के साथ, एक समान वर्ग होता है जिसे एसओएपी अनुरोध के पैरामीटर के रूप में उपयोग किया जाता है। जैसा कि आप ऊपर देख सकते हैं प्रतिक्रिया के लिए एक समान वर्ग भी है।

वर्गों की तरह कुछ (बहुत सरल) दिखेगा:

addStuff = class 
    private 
    FStuff: string; 
    published 
    property stuff: string Index (IS_UNQL) read FStuff write FStuff; 
    end; 

तो जब मैं वेब सेवा मैं उदाहरण के लिए कर फोन:

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; 

(हाँ, मैं जानता हूँ कि मैं कोशिश करना चाहिए था .. अंत में और साथ ही मुफ्त में :-))

फिर, कोड में कहीं और मुझे एक अलग विधि कॉल करने की आवश्यकता है:

procedure listStuff; 
var 
    req: listStuff; 
    res: listStuffResponse; 
    soap: MyWebServicePort; 
begin 
    // Use the function in the wsdl-generated code to create HTTPRIO 
    soap := GetMyWebServicePort(false,'',nil); 
    // Create Parameter Object 
    req := listPhone.Create; 
    req.stuff := 'test2'; 
    // Send the SOAP Request 
    res := soap.listStuff(req); 
end; 

चूंकि मुझे पता है कि पैरामीटर हमेशा एक नाम के साथ एक वर्ग है जो मैं कॉल करने के तरीके के बराबर है, मैं कॉल को गतिशील रूप से आमंत्रित करने के लिए नीचे मेटाकोड की तरह कुछ करने में सक्षम होना चाहता हूं।

procedure soapRequest(Param: Something; var Response: Something); 
begin 
    soap := GetMyWebServicePort(false,'',nil); 
    Response := soap.DynamicInvoke(Param.ClassName, Param); 
end 

तो मैं कुछ ऐसा कर सकता है:: मैं इसे कुछ RTTI जादू की आवश्यकता है, लेकिन मैं एक तरह से यह करने के लिए खोजने के लिए सक्षम किया गया have'nt लगता

soapRequest(VarOfTypeAddStuff,VarOfTypeAddStuffResponse) 
soapRequest(VarOfTypeListStuff,VarOfTypeListStuffResponse) 
... 

किसी को भी एक विचार है कैसे करता है मेरी webservice को कॉल सरलीकृत किया जा सकता है?

+0

यह देखने के लिए कि किसी को भी इस तरह के साथ आता है दिलचस्प होगा, लेकिन मैं सिर्फ आवरण दिनचर्या लिखा था की तरह आप के लिए "छिपाएँ" विवरण है। – mj2008

+3

@ दाहुक: बहुत अच्छी तरह से पहली पोस्ट लिखी गई। वोट दिया एसओ में आपका स्वागत है – RobertFrank

उत्तर

4

यह वास्तव में अजीब बात है कि मैं एक प्रश्न पोस्ट करने के कुछ ही घंटों बाद ही अपने आप को हल करने की कोशिश कर रहा हूं, अचानक मैं बस अपने आप से हल हो जाता हूं ... मैं एसओ पर देखकर प्रेरित था, और मैंने यह पाया जिसने मुझे रास्ते में मदद की: Delphi - Invoke Record method per name

मेरा परिदृश्य मैं कुछ हद तक विशिष्ट हूं, क्योंकि मैं एक पैरामीटर के साथ विधियों को बुला रहा हूं जिसमें विधि के समान वर्ग नाम है। मैंने सरल संस्करण भी लिखा जो सार्वजनिक वेब सेवा के साथ संचार करता है। अगर कोई दिलचस्पी लेता है, तो आप उस के लिए कोड यहां प्राप्त कर सकते हैं: http://www.hook.se/delphi/SoapDynamicInvoke.zip। यह एक बेकार उदाहरण है क्योंकि गतिशील विधि कॉल करना केवल तभी प्रासंगिक होता है जब वेब सेवा में कई अलग-अलग विधियां होती हैं। फिर भी, यह किसी के लिए दिलचस्प हो सकता है :-)

नीचे यह है कि मैंने इसे अपनी वेब सेवा के लिए कैसे हल किया। जैसा कि कहा गया है, यह काफी विशिष्ट है और कोड को और अधिक सामान्य बनाया जा सकता है लेकिन यह मेरे लिए काम करता है।

इस विधि को एक ट्रमोटेबल ऑब्जेक्ट के साथ बुलाया जाता है, और फिर वेब सेवा को ऑब्जेक्ट के क्लास नाम के समान नाम के साथ विधि के साथ बुलाया जाता है।

function soapRequest(Param: TRemotable): TValue; 
var 
    soap: AXLPort; 
    C: TRttiContext; 
    T: TRttiType; 
    M: TRttiMethod; 
    SoapParam: TArray<TValue>; 
    TVres: TValue; 
    soap: MyWebServicePort; 
begin 
    // Use the function in the wsdl-generated code to create HTTPRIO 
    soap := GetMyWebServicePort(false,'',nil); C := TRttiContext.Create; 
    T := C.FindType('MyWebService.MyWebServicePort'); 
    M := T.GetMethod(Param.ClassName); 
    SetLength(SoapParam,1); 
    SoapParam[0] := TValue.From(Param); 
    TVres := M.Invoke(TValue.From<IInterface>(soap), SoapParam); 
    Result := TVres; 
end; 

और ऊपर समारोह का उपयोग करने के:

procedure DoSomeSoapCalls(Sender: TObject); 
var 
    req1: getStuff 
    res1: getStuffResponse; 
    req2: addStuff; 
    res2: addStuffResponse; 
    res: TValue; 
begin 
    //Request #1 
    req1 := getStuff.Create; 
    req1.stuffToGet := 'abc'; 
    try 
    res := soapRequest(req1); 
    res1 := getStuffResponse(res.AsObject); 
    finally 
    req1.Free; 
    end; 
    Writeln(res1.someproperty); 
    FreeAndNil(res1); 

    //Request #2 
    req2 := addStuff.Create; 
    req2.StuffToAdd := 'cde'; 
    try 
    res := soapRequest(req2); 
    res2 := addStuffResponse(res.AsObject); 
    finally 
    req2.Free; 
    end; 
    Writeln(res2.result); 
    FreeAndNil(res2); 
end; 

आवश्यक typecasting का एक सा है, लेकिन मेरे मामले में मुझे लगता है कि मैं उसके साथ बहुत सुरक्षित हो जाएगा। क्या किसी के पास इस बारे में कोई अन्य टिप्पणी/सुझाव है? मेरा मतलब है, यह काम करता है, लेकिन इसे बढ़ाने के लिए शायद तरीके हैं।

चीयर्स,

दान

संबंधित मुद्दे