How to register Datasnap service classes in Runtime on Delphi XE7?

Asked

Viewed 964 times

3

In the Delphi XE3 I was able to register my service classes by doing the following:

type
  TRegisterServices = class
    class procedure RegisterServices(AOwner: TComponent; DSServer: TDSServer);
  private
    class procedure RegisterService(AOwner: TComponent; DSServer: TDSServer;
      AClass: TCustomServiceClass; ALifeCycle: string = TDSLifeCycle.Invocation);
  end;

implementation

class procedure TRegisterServices.RegisterServices(AOwner: TComponent; DSServer: TDSServer);
begin
  RegisterService(AOwner, DSServer, TUsuarioService);
end;

class procedure TRegisterServices.RegisterService(AOwner: TComponent;
  DSServer: TDSServer; AClass: TCustomServiceClass; ALifeCycle: string);
begin
  Assert(AOwner <> nil, 'Serviço ainda não criado');
  Assert(not DSServer.Started, 'Não é possível adicionar classes com o servidor ativo');

  TSimpleServerClass.Create(AOwner, DSServer, AClass, ALifeCycle);
end;

Through this class I registered all my service classes.

To Tsimpleserverclass era:

type
  TSimpleServerClass = class(TDSServerClass)
  private
    FPersistentClass: TPersistentClass;
  protected
    function GetDSClass: TDSClass; override;
  public
    constructor Create(AOwner: TComponent; AServer: TDSCustomServer; 
      AClass: TPersistentClass; ALifeCycle: string = TDSLifeCycle.Invocation); 
      reintroduce; overload;
  end;

constructor TSimpleServerClass.Create(AOwner: TComponent; AServer: TDSCustomServer;  
  AClass: TPersistentClass; ALifeCycle: String);
begin
  inherited Create(AOwner);
  FPersistentClass := AClass;
  self.Server := AServer;
  self.LifeCycle := ALifeCycle;
end;

function TSimpleServerClass.GetDSClass: TDSClass;
var 
  IsAdapted: Boolean; 
begin 
  result := nil; 
  if FPersistentClass <> nil then 
  begin 
    IsAdapted := FPersistentClass.InheritsFrom(TProviderDataModule); 
    result := TDSClass.Create(FPersistentClass, IsAdapted); 
    if IsAdapted then 
      result := TDSClass.Create(TDSProviderDataModuleAdapter, result); 
  end; 
end;

This example no longer works on Delphi XE7:

function TSimpleServerClass.GetDSClass: TDSClass;
var 
  IsAdapted: Boolean; 
begin 
  result := nil; 
  if FPersistentClass <> nil then 
  begin 
    IsAdapted := FPersistentClass.InheritsFrom(TProviderDataModule); 
    result := TDSClass.Create(FPersistentClass, IsAdapted); 
    if IsAdapted then 
      result := TDSClass.Create(TDSProviderDataModuleAdapter, result); 
  end; 
end;

Then I adapted to the following, according to the internal method (it was the same process in previous versions - Delphi XE3, for example):

function TSimpleServerClass.GetDSClass: TDSClass;
var 
  IsAdapted: Boolean; 
  LAdapter: TServerClassAdapter;
begin 
  LAdapter := TServerClassAdapterFactory.GetAdapter(sProviderServerAdapter);
  try
    IsAdapted := (LAdapter <> nil) and LAdapter.IsSupportedType(PersistentClass);
    Result := TDSClass.Create(PersistentClass, IsAdapted);
    if IsAdapted then
      result := TDSClass.Create(LAdapter.GetType, Result);
  finally
    LAdapter.Free;
  end;  
end;  

And all my service classes inherited from:

{$MethodInfo on}
TCustomService = class(TInterfacedPersistent)
private
  FDbConnection: TDbConnection;
  FResponsibleOfConnection: boolean;
public
  constructor Create; reintroduce; overload;
  constructor Create(ADbConnection: TDbConnection); overload;
  destructor Destroy; override;
public
  property DbConnection: TDbConnection read FDbConnection;
end;
{$MethodInfo off}

My methods create and destructor, existing on that standard basis were executed.

Now with the Delphi XE7 I’m not getting to make the method Create run in my inherited service classes from this base class.

As an example:

TUsuarioService = class(TCustomService, IUsuario)
  function TryLogin(ALogin: string; ASenha: string; var AToken: string): boolean;
  function Get(ALogin: string): TUsuario;
  function List: TObjectList<TUsuario>;
  function AddOrUpdate(var AUsuario: TUsuario): boolean;
  function Remove(ALogin: string): boolean;
end;

How to solve such a problem?

  • I solved this problem by declaring Unit "Datasnap.Dsproviderdatamoduleadapter"

2 answers

1

I solved my problem momentarily by making my class TCustomService heiress of TDSServerModule and then make use of the events OnCreate and OnDestroy.

It is not a solution to the problem presented but it is what is helping me at the moment.

I would still like an answer to the problem presented.

0

Hello.. I solved the problem by rewriting the Getdsclass method. I noticed you missed a few lines in your method.

function GetDSClass: TDSClass;
var

  IsAdapted: Boolean;

  LAdapter: TServerClassAdapter;

begin

  LAdapter := TServerClassAdapterFactory.GetAdapter(sProviderServerAdapter);

  try

    IsAdapted := (LAdapter <> Nil) and LAdapter.IsSupportedType(FpersistentClass);

    Result := TDSClass.Create(FPersistentClass, IsAdapted);

    if IsAdapted then

      Result := TDSClass.Create(LAdapter.Getype, Result)

    Finally

      LAdapter.Free;

    end;

  end; 

Browser other questions tagged

You are not signed in. Login or sign up in order to post.