#1 2015-03-05 09:59:30

jaclas
Member
Registered: 2014-09-12
Posts: 215

Registering interface by ServiceRegister (server side)

The examples show how to register in server a class that implements the ICalculator interface.

  ICalculator = interface(IInvokable)
  ['{E7014BA0-007E-4DCB-9C34-4A8CCB2BF9C3}']
   function Suma(A, B : Integer): Integer;
   function GetName : string;
  end;

  TCalculator = class(TInterfacedObject, ICalculator)
  public
    function Suma(A, B : Integer): Integer;
    function GetName : string;
  end;

And now the registration and use:

var
 aModel: TSQLModel;
begin
 aModel := TSQLModel.Create([],ROOT_NAME);
 try
  with TSQLRestServerDB.Create(aModel,ChangeFileExt(paramstr(0),'.db'),true) do
  try
   ServiceRegister(TServiceCalculator,[TypeInfo(ICalculator)],sicShared);
   ExportServerNamedPipe(APPLICATION_NAME);
   readln;
  finally
   Free;
  end;
 finally
  aModel.Free;
 end;
end.

But I would like to register interface on the server, not a object/class. So this:

var
 aModel: TSQLModel;
 liCalculator : ICalculator;
begin
 aModel := TSQLModel.Create([],ROOT_NAME);
 try
  with TSQLRestServerDB.Create(aModel,ChangeFileExt(paramstr(0),'.db'),true) do
  try

   liCalculator := GetImplementorOfInterface(ICalculator); <----- get interface implementation
   ServiceRegister(liCalculator,[TypeInfo(ICalculator)],sicShared); <--------- register instance of interface!

   ExportServerNamedPipe(APPLICATION_NAME);
   readln;
  finally
   Free;
  end;
 finally
  aModel.Free;
 end;
end.

In my code I operate mainly on interfaces, I don't want to mix object access and interface access. In addition, I would like to have separated implementation of interfaces, because I can easily swap between the implementations (on configuration level).

Is this possible? Can you add this functionality? :-)

thx

Offline

#2 2015-03-05 11:17:31

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,662
Website

Re: Registering interface by ServiceRegister (server side)

Why is not the following TSQLRestServer method OK for you:

    /// register a Service instance on the server side
    // - this methods expects a class instance to be supplied, and the exact list
    // of interfaces to be registered to the server (e.g. [TypeInfo(IMyInterface)])
    // and implemented by this shared instance
    // - as a consequence, instance implementation pattern will always be sicShared
    // - will return the first of the registered TServiceFactoryServer created
    // on success (i.e. the one corresponding to the first item of the aInterfaces
    // array), or nil if registration failed (e.g. if any of the supplied interfaces
    // is not implemented by the given class)
    // - you can use the returned TServiceFactoryServer instance to set the
    // expected security parameters associated with this interface
    // - the same implementation class can be used to handle several interfaces
    // (just as Delphi allows to do natively)
    function ServiceRegister(aSharedImplementation: TInterfacedObject;
      const aInterfaces: array of PTypeInfo): TServiceFactoryServer; overload; virtual;

See also the following function, if you want to store only interfaces variables, and sometimes expect to retrieve the class instance from it:

/// low-level function to retrieve the class instance implementing a given
// interface
// - this will work with interfaces stubs generated by the compiler, but also
// with TInterfaceFactory.CreateFakeInstance kind of classes
function ObjectFromInterface(const aValue: IInterface): TObject;

So you can write:

  aServer.ServiceRegister(ObjectFromInterface(aInterfaceVariable) as TInterfacedObject,[TypeInfo(IInterfaceOfTheVariable)]);

Offline

Board footer

Powered by FluxBB