Reputation: 2451
I have a type of TestTopicNotificationHandler
and I wish to get the MessageBusSubscription
attributes attached to the handle method of any ITopicNotificationHandler<> method that is implemented within the class.
There a couple of scenarios:
Task Handle(OtherNotification notification)
Handle
as in this case it would pickup Task Handle(bool notAnInterfaceImplementation)
which his not actually a signature of ITopicNotificationHandlerITopicNotificationHandler
), but not defined in the class interface listHow can i achieve the above please, to find the linked implementation and pull the attribute from it (without reflecting by method name) similar to below:
var type = typeof(TestTopicNotificationHandler);
var attributes = FindAttributes(type);
// above function call returns the attributes that are defined in the class
// { [MessageBusSubscription("v1\test", QualityOfService.AtMostOnce)], [MessageBusSubscription("v1\yes", QualityOfService.AtMostOnce)]
Where this would be a typical class implementation:
class TestTopicNotificationHandler : ITopicNotificationHandler<TestTopicNotification>, ITopicNotificationHandler<YesNotification>, ITopicNotificationHandler<OtherNotification>
{
[MessageBusSubscription("v1\test", QualityOfService.AtMostOnce)]
public Task Handle(TestTopicNotification notification)
{
return Task.CompletedTask;
}
[MessageBusSubscription("v1\yes", QualityOfService.AtMostOnce)]
public Task Handle(YesNotification notification)
{
return Task.CompletedTask;
}
// this should be ignored as whilst listed, it does not have an attribute attached
public Task Handle(OtherNotification notification)
{
return Task.CompletedTask;
}
// this should be ignored as whilst valid interface signature, it is not listed in the implementation list of the class
public Task Handle(NonListedNotification notification)
{
return Task.CompletedTask;
}
// this should be ignored it is not an interface
[MessageBusSubscription("invalid", QualityOfService.AtMostOnce)]
public Task Handle(bool notAnInterfaceImplementation)
{
return Task.CompletedTask;
}
}
Upvotes: 0
Views: 800
Reputation: 42350
You can use Type.GetInterfaceMap
to do something like this:
var type = typeof(TestTopicNotificationHandler);
foreach (var implementedInterface in type.GetInterfaces())
{
if (!implementedInterface.IsGenericType
|| implementedInterface.GetGenericTypeDefinition() != typeof(ITopicNotificationHandler<>))
continue;
var interfaceMap = type.GetInterfaceMap(implementedInterface);
foreach (var implementedMethod in interfaceMap.TargetMethods)
{
var attribute = implementedMethod.GetCustomAttribute<MessageBusSubscriptionAttribute>();
if (attribute == null)
continue;
Console.WriteLine($"{implementedMethod.Name}: {attribute.Path}");
}
}
We find all of the ITopicNotificationHandler
interfaces that the type implements. For each one, we get a mapping which maps the methods defined on the interface to the corresponding methods defined on the type. We loop through each of the corresponding methods defined on the type, and look at the attributes for each.
Upvotes: 1
Reputation: 11919
I want to avoid looking up via function name - Why is this a requirement?
Anyway, here is a solution that finds all methods called Handle
, that have the MessageBusSubscription attribute:
var allMethods = typeof(TestTopicNotificationHandler).GetMethods();
var handleMethods = allMethods.Where(x=>x.Name=="Handle");
foreach(var method in handleMethods)
{
var attr = method.GetCustomAttributes(typeof(MessageBusSubscription));
if(attr.Any())
{
// Here you have the method with the attribute.
}
}
It should be pretty easy to adapt this to also look up the methods defined in the interface and ignore them.
Upvotes: 0