Disponibilizando métodos de uma classe como Server Methods sem usar TServerModule em DataSnap

Categories:DelphiTags: , ,

Hoje certamente você tem diversas classes contendo regras de negócios que poderiam ser melhor aproveitas em uma aplicação multicamada desenvolvida em Delphi. Por meio dos Server Methods é possível fazer isso tranquilamente.

Para uma classe ser disponibilizada como Server Methods é necessário:

  • Descender de TPersistent
  • Ter a diretiva {$MethodInfo ON}, esta diretiva permite ao DataSnap obter informações da classe a partir da RTTI
  • Estar registrada através do componente DSServerClass

Abaixo exemplo de uma classe que não é descendente de TDSServerModule e sim de TPersistant, podemos assumir que esta classe já existia anteriormente e que agora queremos reusar em nosso servidor DataSnap

unit User;

interface

uses
  BaseServerClass,
  Classes,
  DBXCommon,
  SysUtils,
  Dialogs,
  MainServerModule;

type
{$METHODINFO ON}
  TUser = class(TPersistent)
  private

  public
    constructor Create;
    destructor Destroy; override;

    procedure AddUser(FirstLastName, Login, Password: String);

    function IsValidUser(Login, Password: String): Boolean;

    procedure DisableUser(Login: String);
    procedure EnableUser(Login: String);

  end;

implementation

uses
  ServerContainer;

{ TUser }

procedure TUser.AddUser(FirstLastName, Login, Password: String);
var
  Comm: TDBXCommand;
begin

  if (FirstLastName = '') then
    raise Exception.Create('First/Last name is required');

  if (Login = '') then
    raise Exception.Create('Login is required');

  if (Password = '') then
    raise Exception.Create('Password is required');

  Comm := FDbxConnection.CreateCommand;

  Comm.Text :=
    'Insert Into Users (NAME, LOGIN, PASSWORD, ACTIVE ) Values (' + QuotedStr
    (FirstLastName) + ',' + QuotedStr(Login) + ',' + QuotedStr(Password)
    + ', true)';
  Comm.ExecuteQuery;

  FreeAndNil(Comm);

end;

constructor TUser.Create;
begin
  FDbxConnection := DMServerContainer.DataSnap_Server_Log.DBXConnection;
end;

destructor TUser.Destroy;
begin

  inherited;
end;

procedure TUser.DisableUser(Login: String);
var
  Comm: TDBXCommand;
begin

  if (Login = '') then
    raise Exception.Create('Login is required');

  Comm := FDbxConnection.CreateCommand;

  Comm.Text := 'Update Users Set ACTIVE = False Where LOGIN = ' + QuotedStr
    (Login);
  Comm.ExecuteQuery;

  FreeAndNil(Comm);

end;

procedure TUser.EnableUser(Login: String);
var
  Comm: TDBXCommand;
begin

  if (Login = '') then
    raise Exception.Create('Login is required');

  Comm := FDbxConnection.CreateCommand;

  Comm.Text := 'Update Users Set ACTIVE = True Where LOGIN = ' + QuotedStr
    (Login);
  Comm.ExecuteQuery;

  FreeAndNil(Comm);

end;

function TUser.IsValidUser(Login, Password: String): Boolean;
var
  Comm: TDBXCommand;
  Reader: TDBXReader;
begin
  if (Login = '') then
    raise Exception.Create('Login is required');

  if (Password = '') then
    raise Exception.Create('Password is required');

  Comm := FDbxConnection.CreateCommand;

  Comm.Text := 'Select ACTIVE From Users Where LOGIN = ' + QuotedStr(Login)
    + ' and PASSWORD = ' + QuotedStr(Password);

  Reader := Comm.ExecuteQuery;

  if Reader.Next then
  begin
    Result := Reader.Value[0].GetBoolean;
  end
  else
    Result := False;

  Reader.Close;
  FreeAndNil(Reader);
  FreeAndNil(Comm);

end;

end.

Quer saber mais sobre DataSnap, clique aqui.

Posts relacionados

6 Responses to Disponibilizando métodos de uma classe como Server Methods sem usar TServerModule em DataSnap

  1. Bruno Pegoraro says:

    E se um desses métodos remotos chamasse internamente um método de uma DLL local (no servidor de aplicação) ??
    Esse é meu caso e quanto tento invocar o método da aplicação cliente retorna o seguinte erro:

    Remote error: CoInitialize não foi chamado, ClassID: {1B72700B-9A17-35C4-B2C6-5C84A6CF7C1D}

  2. Andreano Lanusse says:

    Bruno, isso não é problema para o DataSnap, como não tenho o seu código fica difícil de entender o que está acontecendo, mas pela mensagem está dizendo que você não chamou o método CoInitialize, parece ter chamadas OLE na sua DLL, então ao subir seu servidor DataSnap execute este método.

  3. Paulo says:

    Olá Andreano,

    primeiramente ótima materia, estou tentando usar seu exemplo acima com uma diferença – usar o Overload em umas das chamadas, mas o delphi nao me permite compilar o projeto retornando o sequinte erro :
    [DCC Error] User.pas(26): E1030 Invalid compiler directive: ‘OVERLOAD’

    os metodos descendidos de TPersistent não aceitam o Overload ?
    tem ideia de qual seria o problema de fazer overload em procedure e functions usando o DataSnap ?

    Obrigado.

  4. Júlio César Ferreira (@jcmferreira) says:

    Essa dica de como disponibilizar métodos “server methods” sem utilizar o TServerModule é perfeita! Salvou-me de muitas dúvidas ainda não respondidas…

    O ruim do DataSnap é que, uma vez nele, vc quer sempre muito mais.

    Gostaria muito de saber um pouco mais sobre a parte de autenticação de usuários, sessões via TCP/IP e controle do cache de dados. Quando surgir algo do tipo por aqui, vai ser ótimo! ;)

    Parabéns pelo blog!

  5. Júlio César Ferreira (@jcmferreira) says:

    Bom dia Andreano!

    Sobre essa solução na criação de ServerMethods em runtime, o registro dela através do componente DSServerClass precisa ser feito em que momento? No meu ServerContainer, que possui o DSServer ou na própria declaração da classe, como essa TUser?

    Tentei criar uma classe como a do seu exemplo, TSimpleServerClass = class(TDSServerClass), e instanciei a mesma no meu ServerContainer. O registro de uma classe qualquer minha até funiona mas o meu cliente datasnap não consegue enxergar o provider dela…

    Existe alguma coisa a mais para ser feita ou de forma diferente para que isso funcione?

  6. Júlio César Ferreira (@jcmferreira) says:

    Com relação ao post anterior Andreano… a mensagem de erro é “Resource TServerMethodsFilial not found”

    P.S.: A classe TServerMethodsFilial, herdando de TPersistent, é a classe que quero referenciar como ServerMethods em meu projeto…

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>