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.
