Also wir benutzen Interfaces. Das hat den enormen Vorteil, dass die reine
DLL Schnittstelle sehr schlank sein kann. Wir haben eine Funktion in der
DLL, die von der Anwendung aufgerufen wird nachdem die
DLL geladen ist. Diese bekommt das Anwendungsinterface. Darüber meldet sich umgekehrt die
DLL an der Anwendung an und übergibt ebenfalls ein Interface.
Darüber können nun Interfaces bei der Anwendung registriert oder angefordert werden.
Es gibt eine Klasse TApplicationInterface, die das ganze kapselt. Und dann geht das ganze direkt generisch. Zum Beispiel funktioniert dann das sowohl in
DLL als auch in der Anwendung:
Delphi-Quellcode:
var
Params: IInterfaceGetterParams;
Data: IDataset;
begin
Params := TDatabaseGetterParams.Create(TDatasetKind.Query, 'select * from foo');
Data := TApplicationInterface.Get<IDataset>(Params);
while not Data.Eof do
...
Interfaces kennen ja nun keine generischen Methodenparameter. Das funktioniert daher, indem die Klassenmethode Get die
GUID des generischen Parameters ermittelt und über das Interface an der Hauptanwendung diese
GUID und das Parameterinterface übergibt. Dort wird dann über die
GUID die registrierte Factorymethode ermittelt, mit der das Interface geholt werden kann, und mit dem Parameterinterface aufgerufen.
Natürlich kann man bei wenigen Interfaces (bei uns sind es eben sehr viele) auch im Interface der Hauptanwendung direkt z.B. eine Methode GetDataset: IDataset usw. anlegen und braucht keine Generics dafür.