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.
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).
LikeLike
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
LikeLike