#1 2013-05-03 12:52:57

Roberto Schneiders
Member
From: Santa Catarina, Brazil
Registered: 2012-09-19
Posts: 127
Website

ServiceRegister and TServiceInstanceImplementation in Client Side

I have a question regarding the service register.

Server.ServiceRegister(TServiceCalculator,[TypeInfo(ICalculator)],sicShared)
Client.ServiceRegister([TypeInfo(ICalculator)],sicShared);

I am forced to register services on both the server and the client. Ok, I suppose we need the interfaces information in the Client Layer, and so need to run the client ServiceRegister. However, do not understand why I have to reenter the TServiceInstanceImplementation (eg sicShared)!
And if I inform different things on the client and server, what can happen?

Offline

#2 2013-05-03 13:25:04

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

Re: ServiceRegister and TServiceInstanceImplementation in Client Side

The contract signature is checked, and if the ICalculator is not the same on both sides, there will be an explicit exception for the client.

Offline

#3 2013-05-03 13:33:53

Roberto Schneiders
Member
From: Santa Catarina, Brazil
Registered: 2012-09-19
Posts: 127
Website

Re: ServiceRegister and TServiceInstanceImplementation in Client Side

Got it. I'm thinking of a way to facilitate the use of interfaces for developers. But not reached a conclusion yet. Imagine that developers who make the server are not the same that will implement the client.

Another thing. I'm not pleased about having to use an identifier of type String to get the service. Like that:

var
  Calculator: ICalculator;
begin
  Client.Services['Calculator'].Get(Calculator);
end;

It would not be possible to have something like this?

var
  Calculator: ICalculator;
begin
  Client.GetService(Calculator);
end;

Maybe we can get the identifier via RTTI, what do you think?

Last edited by Roberto Schneiders (2013-05-03 13:35:13)

Offline

#4 2013-05-03 14:39:08

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

Re: ServiceRegister and TServiceInstanceImplementation in Client Side

The ICalculator is the contract.

It is to be shared between client and server.

It is IMHO a much better approach than generating a client.
In SOAP/WCF it is just a nightmare to generate clients wrappers, from my experiment.

Whereas a shared unit with the interface type definition is just clean and easy.

You have to use the overloaded method, using the RTTI, i.e. TypeInfo(ICalculator).

Using generics, we may be able to write something like:

Client.GetService<ICalculator>(Calculator);

but I do not think it is better than:

Client.GetService(TypeInfo(ICalculator),Calculator);

... and will generate much more code.

Offline

#5 2013-05-03 17:27:20

Roberto Schneiders
Member
From: Santa Catarina, Brazil
Registered: 2012-09-19
Posts: 127
Website

Re: ServiceRegister and TServiceInstanceImplementation in Client Side

ab wrote:

The ICalculator is the contract.

It is to be shared between client and server.

It is IMHO a much better approach than generating a client.
In SOAP/WCF it is just a nightmare to generate clients wrappers, from my experiment.

Whereas a shared unit with the interface type definition is just clean and easy.

That is ok. I agree.

ab wrote:

You have to use the overloaded method, using the RTTI, i.e. TypeInfo(ICalculator).

Using generics, we may be able to write something like:

Client.GetService<ICalculator>(Calculator);

but I do not think it is better than:

Client.GetService(TypeInfo(ICalculator),Calculator);

... and will generate much more code.

Certainly any of these methods would already be great. Some of them already exist?
How I have not found this method in class TSQLHttpClient, I deduce not!

I like the implementation with generics, but as it only works in the newer versions of Delphi is not very useful for us.
An even simpler implementation without generics, might look like:

Client.GetService(ICalculator,Calculator);

with generics:

Calculator := Client.GetService<ICalculator>;

Offline

#6 2013-05-07 13:08:38

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

Re: ServiceRegister and TServiceInstanceImplementation in Client Side

Calculator := Client.GetService<ICalculator>;

is a valid Delphi syntax, which I just implemented with a new TSQLRest.Service<T: IInterface> method.

For newer generic-aware versions of Delphi (i.e. Delphi 2010 and up, since Delphi 2009 is buggy about generics), you can use such a method, which enabled compile-time checking:

var I: ICalculator;
begin
  I := Client.Service<ICalculator>;
  if I<>nil then
    result := I.Add(10,20);
end;

See http://synopse.info/fossil/info/783a67b6d3
(feel free to propose any other syntax extension using generics)

BUT

Client.GetService(ICalculator,Calculator);

will never compile.
There is not "class of IMyInterface" kind of type, as we have "class of TMyClass" in the Delphi syntax, AFAIK.
This is why we are required to use TypeInfo(ICalculator).

In fact, Client.Service<ICalculator> is just a wrapper around Clients.Services.Info(TypeInfo(ICalculator)).Get().

Offline

#7 2013-05-08 11:15:56

Roberto Schneiders
Member
From: Santa Catarina, Brazil
Registered: 2012-09-19
Posts: 127
Website

Re: ServiceRegister and TServiceInstanceImplementation in Client Side

ab wrote:
Calculator := Client.GetService<ICalculator>;

is a valid Delphi syntax, which I just implemented with a new TSQLRest.Service<T: IInterface> method.

For newer generic-aware versions of Delphi (i.e. Delphi 2010 and up, since Delphi 2009 is buggy about generics), you can use such a method, which enabled compile-time checking:

var I: ICalculator;
begin
  I := Client.Service<ICalculator>;
  if I<>nil then
    result := I.Add(10,20);
end;

Excellent. Thank you.

ab wrote:

See http://synopse.info/fossil/info/783a67b6d3
(feel free to propose any other syntax extension using generics)

BUT

Client.GetService(ICalculator,Calculator);

will never compile.
There is not "class of IMyInterface" kind of type, as we have "class of TMyClass" in the Delphi syntax, AFAIK.
This is why we are required to use TypeInfo(ICalculator).

In fact, Client.Service<ICalculator> is just a wrapper around Clients.Services.Info(TypeInfo(ICalculator)).Get().

It is true. Sorry.

Offline

Board footer

Powered by FluxBB