Olá!
Este é o tipo de dica que a gente acha que nunca vai usar.
:D
Eu uso o KBM para construir sistemas em N Camadas:
http://www.components4programmers.com/.
Para a construção de um RPC ( estou indo direto ao ponto, em caso de dúvidas sobre o assunto me contacte ) a sugestão é encadear um monte de IF como no exemplo abaixo:
// Master request processor.
//--------------------------
function TkbmRPCDatabase.ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
afunc : string;
begin
Self.GerarLog(Format('Func: [%s]',[Func]), 0001, ctLOGGExpert,rlLow);
try
AFunc:=UpperCase(Func);
if AFunc='TESTE' then
Result := PerformTESTE(ClientIdent,Args)
else Result:=inherited ProcessRequest(Func,ClientIdent,Args);
except
on E: Exception do
begin
Self.GerarLog(DescreverException(E),0001, ctLOGGExpert,rlLow );
raise;
end;
end;
end;
Ou seja, se eu tiver
n funções, teria que encadear um
if..else que na minha opnião fica asqueroso de se dar manutenção além de obviamente não ser "performático".
A solução definitiva apareceu nesse tópico:
http://delphi.about.com/cs/adptips2004/a/bltip0204_3.htm
Note o seguinte: O seu método tem que estar na parte
published da sua classe. Em outras sessões não rola.
Veja como ficou o código:
// Master request processor.
//--------------------------
function TkbmRPC_CSAS.ProcessRequest(const Func:string; const ClientIdent:TkbmMWClientIdentity; const Args:array of Variant):Variant;
var
sFunc : string;
rRoutine : TMethod;
_perform : TPerformFunction;
begin
Self.GerarLog(Format('Executando: [%s] - [%s]',[Func,ClientIdent.RemoteLocation]),322382429,ctLOGInformation,rlMiddle);
sFunc := Format('Perform%s',[Func]);
rRoutine.Data := Pointer(Self);
rRoutine.Code := Self.MethodAddress(sFunc);
if (Assigned(rRoutine.Code)) then
begin
_perform := TPerformFunction(rRoutine);
Result := _perform(ClientIdent,Args);
end else
begin
inherited ProcessRequest(Func,ClientIdent,Args);
end;
end;
Para isso tudo funcionar, tive que criar um tipo especial:
interface
uses
kbmMWSecurity;
type
{$M+}
///Usado para permitir uma chamada dinâmica às funções dos RPCs
TPerformFunction = function(ClientIdent:TkbmMWClientIdentity; const Args:array of Variant): Variant of object;