Sometimes when you are creating the architecture and defining the interfaces you can slick down to a copy-paste for a simple files (when you now it some really similar ones and you just need to change some names etc.). So you copy the file, adjust all the things – that all seems valid. But it can happen that you forgot to regenerate the GUID with Ctrl+Shift+G. And a different interface is declared with the same GUID as absolutely different one. In good scenario you should find it immediately – because you do the tests, run them, see the issue and fix the source. But in case you already have a bunch of units and you want to validate that no interfaces are using the same GUID you can use following simple code (it is simplified, the full version is mentioned below the code) to find them:
var LType: TRttiType; LIntf: TRttiInterfaceType; LTypes: IList<TRttiInterfaceType>; begin Result := TCollections.CreateMultiMap<TGUID, TRttiInterfaceType>; LTypes := TCollections.CreateList<TRttiInterfaceType>; for LType in FCtx.GetTypes do if (LType.TypeKind = tkInterface) and (TRttiInterfaceType(LType).GUID <> TGUID.Empty) then LTypes.Add(TRttiInterfaceType(LType)); 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;
I do use the Spring4D framework there. The use of it is completely optional (you can adjust the code to avoid using it). The complete source code of the class can be found at GitHub. As well there is the demo project demonstrating such an issue.
Thank you for reading the post. I hope you find anything useful there.
Is it just coincidence that there was a similar question on StackOverflow today with one answer with a similar solution? Or was it you who answered the question?
Yes. It was me. But i first wrote this post. And then Googled and found that there was a question on SO.. I wrote the post source yesterday already.