Hi,
To be able to check if an instance implements a given interface, that interface needs to have a defined GUID. So, add a guid to your interface (you'll also need this guid in a const or variable so you may refernce it later in code):
const
IID_Handle: TGUID = '{0D3599E1-2E1B-4BC1-ABC9-B654817EC6F1}';
type
IHandle<TMessage> = interface
['{0D3599E1-2E1B-4BC1-ABC9-B654817EC6F1}']
procedure Handle(AMessage: TMessage);
end;
(You shouldn't use my guid, it's just an example.. press ctrl+shift+G to generate a new guid in the IDE).
Then check to see if the registered subscriber supports this interface:
// LTarget:= LReference as IHandle; // <-- Wish this would work
if Supports(LReference, IID_Handle, LTarget) then
LTarget.Handle(AMessage);
However, this doesn't take the generic part of the interface into account, it only checks the GUID.
So you'll need some more logic around this to check if the target actually supports the message type.
Also, since you're dealing with classes that will be implementing an interface, and thus should derive from TInterfacedObject (or a compatible interface to that class) you should keep all references to the created object in interface variables, thus change the subscrber list from a reference to TObjects' to one of IInterfaces'. And there is a specific class for that, too:
FSubscribers: TInterfaceList;
Of course, you'll have to change the signature to the subscribe/unsubscribe functions too:
procedure Subscribe(AInstance: IInterface);
procedure Unsubscribe(AInstance: IInterface);
I think a better way would be to take out the generic of the IHandle interface. That way you can enforce that all subscribers implement the basic IHandler interface by changing the subscribe/unsibscribe signature to take IHandler instead of IInterface.
IHandler can then hold the functionality required to determine if the subscriber supports the given message type or not.
This will be left as an excercise to the reader. You might want to start with my little test app (D2010) which you can download from My Test App.
N.B. The test app explores the possibility of using generics in the interface, and will most likely crash when publishing events. Use the debugger to single step to see what happens. I doesn't crash when publishing integer 0, which seems to work.
The reason is that both Int and String handler will be called regardless of input type to Publish (as discussed earlier).