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.