Due to the current implementation pattern of the TCollection
type in Delphi, it was not possible to implement directly this kind of
parameter.
In fact, the TCollection
constructor is defined as such:
constructor Create(ItemClass: TCollectionItemClass);
And, on the server side, we do not know which kind of
TCollectionItemClass
is to be passed. Therefore, the
TServiceFactoryServer
is unable to properly instantiate the object
instances, supplying the expected item class.
So a dedicated TInterfacedCollection
abstract type has been
defined:
TInterfacedCollection = class(TCollection) protected function GetClass: TCollectionItemClass; virtual; abstract; public constructor Create; reintroduce; virtual; end;
In order to use a collection of objects, you will have to define at least the abstract method, for instance:
TCollTests = class(TInterfacedCollection) protected function GetClass: TCollectionItemClass; override; end;
function TCollTests.GetClass: TCollectionItemClass; begin result := TCollTest; end;
Or, if you want a more complete / convenient implementation:
TCollTests = class(TInterfacedCollection) private function GetCollItem(Index: Integer): TCollTest; protected function GetClass: TCollectionItemClass; override; public function Add: TCollTest; property Item[Index: Integer]: TCollTest read GetCollItem; default; end;
Then you will be able to define a contract as such:
procedure Collections(Item: TCollTest; var List: TCollTests; out Copy: TCollTests);
A typical implementation of this contract may be:
procedure TServiceComplexCalculator.Collections(Item: TCollTest; var List: TCollTests; out Copy: TCollTests); begin CopyObject(Item,List.Add); CopyObject(List,Copy); end;
That is, it will append the supplied Item
object to the
provided List
content, then return a copy in the Copy
content:
- Setting Item
without var
or out
specification is doing the same as const
: it will be serialized
from client to server (and not back from server to client);
- Setting List
as var
parameter will let this
collection to be serialized from client to server, and back from server to the
client;
- Setting Copy
as out
parameter will let this
collection to be serialized only from server to client.
Note that const / var / out
kind of parameters are used at the
contract level in order to specify the direction of serialization, and not as
usual (i.e. to define if it is passed by value or by
reference). All class
parameters shall be instantiated before
method call: you can not pass any object parameter as nil (nor use it in a
function result): it will raise an error.
Feedback is welcome on our forum.