Finding used but unimplemented interfaces

When reusing the implementation and interfaces between different tools/projects some of us face the problem getting run-time error about some interface implementation not found. It can be the case when you use service locator (avoid them) or any other mechanisms when your implementation class are registering in the factories (or similar) in the initialization section of the source units.

But the topic is not about these mechanisms – I just wanted to share with you a code which allows you to list unimplemented interfaces in your application. Of course using our beloved reflection 🙂

var
 LType: TRttiType;
 LIntf: TRttiInterfaceType;
 LTypes: IList<TRttiInterfaceType>;
begin
  { Create the result instance }
  Result := TCollections.CreateMultiMap<TGUID, TRttiInterfaceType>;

  { Get all the types }
  LTypes := TCollections.CreateList<TRttiInterfaceType>;

  { Build the multimap }
  for LType in FCtx.GetTypes do
    { Add only classes and interfaces }
    if LType.TypeKind = tkInterface then
      { Skip interfaces which does not have GUID }
      if TRttiInterfaceType(LType).GUID <> TGUID.Empty then
        begin
          { Handle user filter }
          if Assigned(AFilter) then
            if not AFilter(TRttiInterfaceType(LType)) then
              Continue;

          LTypes.Add(TRttiInterfaceType(LType));
        end;

  { For all interaces }
  for LIntf in LTypes do
    if LTypes.Any(
      function (const AType: TRttiInterfaceType): Boolean
      begin
        Result := 
          (AType.GUID = LIntf.GUID) and 
          (LIntf.QualifiedName <> AType.QualifiedName);
      end) then
    Result.Add(LIntf.GUID, LIntf);
end;

The complete unit is available on GitHub. So once you add the unit to your project you can write following lines to get the list of interfaces:

uses
  ...,  
  uInterfaces.NotImplemented;
...
var
 T: TRttiInterfaceType;
begin
 AllocConsole;
 for T in InterfacesNotImplemented.List do
   Writeln(T.QualifiedName);
 ...
end.

This way it will enough once to compile and run your project to get the list of interfaces which are used in your project but are not implemented. Of course by default the function will return you the list of some system interfaces, but you can filter them out manually later.

Thank you for reading and I hope the information provided will be of some use for you.

2 comments

  1. If you use a mocking library, your code will not identify mocked class instances generated at runtime. And mocking may be used not only for testing purposes, but also for some automated process common to one interface (like persistence or redirection).

    Like

    1. Sure. The code does what it does. You can always find and develop solutions which will not fit. TVirtualInteface will be not detected. But the post is not about such cases

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s