It turns out I was massively over-thinking or over-engineering this.
Instead I add the handler classes to the Unity container using the name of the definition class that the handler handles.
Public Shared Function GetNameFromCommandDefinition(ByVal handler As Type) As String
Dim handlerInterface As Type = handler.GetInterface("ICommandHandler`1", False)
If (handlerInterface IsNot Nothing) Then
If (handlerInterface.GetGenericArguments.Count > 0) Then
Return handlerInterface.GetGenericArguments(0).Name
End If
End If
Return handler.Name()
End Function
and you call this function in the Unity registration code thus:-
Public Shared Sub RegisterTypes(container As IUnityContainer)
Dim interfaceType As Type = Nothing
interfaceType = GetType(ICommandHandler(Of ))
container.RegisterTypes(AllClasses.FromAssembliesInBasePath(includeUnityAssemblies:=False, includeSystemAssemblies:=False).Where(Function(t) t.ImplementsInterface(interfaceType)),
getName:=Function(i) GetNameFromCommandDefinition(i),
getLifetimeManager:=Function(i) WithLifetime.PerThread(i))
End Sub
It's still not 100% resolved (no pun intended) but I am heading in the right direction...