How to register Datasnap service classes at runtime in Delphi XE7?

Question:

In 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 classes of service.

The TSimpleServerClass was:

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;

So I adapted it to the following, according to the internal method (it was the same process as 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 classes of service 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 create and destructor methods, existing in this default base were executed.

Now with Delphi XE7 I'm not getting the Create method to be executed in my service classes inherited from this base class.

For 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 this problem?

Answer:

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

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.

Scroll to Top