How to obtain GUID of interface passed as a generic parameter in Delphi?

Viewed 174

In the following, the method Obtain() works, but the GetAs() method would be neater for callers.

However, I can't figure out how to pass an interface as a generic parameter and obtain its GUID.

Declaration:

  TInterfaceRegistry = class
  private
    fRegistry: TDictionary<TGUID, IInterface>;
  public
    ...
    procedure Register(const IID: TGUID; IntfObj: IInterface; const Replace: Boolean = False);
    function  Obtain(const IID: TGUID; out IntfObj): Boolean;
    function  GetAs<I: IInterface>(): I;
  end;

Implementation:

function TInterfaceRegistry.Obtain(const IID: TGUID; out IntfObj): Boolean;
var
  Found: IInterface;
begin
  Result  := fRegistry.TryGetValue(IID, Found);
  if  Result  then
    if  not Supports(Found, IID, IntfObj) then
      raise EBatSoft.Create(SEBatSoftBug);
end;

function  TInterfaceRegistry.GetAs<I>(): I;
begin
  if  not Obtain(I, Result) then
    raise EBatSoft.Create(SEDoesNotImplement);
end;

Calling it looks like this...

  IntfReg.Register(IMyIntf, TMyImpl.Create);

Getting implementation:

var
  Intf: IMyIntf;
begin
  // Less type-safe (can pass anything into 2nd parameter)
  if IntfReg.Obtain(IMyIntf, Intf)  then
    ...
  // Fully type-safe, and simple
  Intf := IntfReg.GetAs<IMyIntf>();
1 Answers

You have to use typeinfo via GetTypeData(TypeInfo(I)).GUID.

Keep in mind though this might return an empty guid if you did not declare any for the given interface you are using while the non generic approach simply would not compile.

Related