I need to interact with series of .Net web services. There are currently about 150. Since delphi 2010 uses Thttprio to achieve this, I am trying to create a generic Proxy on the client side that can be called to create the appropriate soap service client. Does anyone have any idea how I can cast the httprio object to a generic interface type?
Thanks
Below is the proxy function I'm trying to use:
class function Web.Proxy<T>(svc: string): T;
var
HTTPRIO : THTTPRIO;
begin
HTTPRIO := THTTPRIO.Create(nil);
HTTPRIO.URL := GetServiceURL(svc);
Result:= HTTPRIO as T; //<-- Fails with "operator not applicable to this operand type"
// Result:= T(HTTPRIO); //<-- also fails, but with "invalid typecast"
end;
The idea is that I can call this with:
Web.Proxy<AutmobileServiceSoap>('svc.asmx').GetAutomobile(125);
The WSDL import has the AutmobileServiceSoap defined as follows:
AutmobileServiceSoap = interface(IInvokable)
And all the wsdl imports have a function that returns the httprio object cast in a similar manner:
function GetAutomobileServiceSoap(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): AutomobileServiceSoap;
const
defWSDL = 'http://localhost:8732/Cars.Server/Data/AutomobileService.asmx?WSDL';
defURL = 'http://localhost:8732/Cars.Server/Data/AutomobileService.asmx';
defSvc = 'AutomobileService';
defPrt = 'AutomobileServiceSoap12';
var
RIO: THTTPRIO;
begin
Result := nil;
if (Addr = '') then
begin
if UseWSDL then
Addr := defWSDL
else
Addr := defURL;
end;
if HTTPRIO = nil then
RIO := THTTPRIO.Create(nil)
else
RIO := HTTPRIO;
try
Result := (RIO as AutomobileServiceSoap);
if UseWSDL then
begin
RIO.WSDLLocation := Addr;
RIO.Service := defSvc;
RIO.Port := defPrt;
end else
RIO.URL := Addr;
finally
if (Result = nil) and (HTTPRIO = nil) then
RIO.Free;
end;
end;
You have to use RTTI to get the GUID of the interface
type
Web = class
class function Proxy<T: IInterface>(svc: string): T;
end;
class function Web.Proxy<T>(svc: string): T;
var
HTTPRIO: THTTPRIO;
data: PTypeData;
begin
HTTPRIO := THTTPRIO.Create(nil);
HTTPRIO.URL := GetServiceURL(svc);
data := GetTypeData(TypeInfo(T));
if ifHasGuid in data.IntfFlags then
begin
HTTPRIO.QueryInterface(data.Guid, Result);
end;
end;
If you specify the IInterface constraint you can be sure that T is always an interface (otherwise you have to check the TypeKind of the TypeInfo also).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With