samedi 25 juillet 2020

Using reflection to annotated methods that have attributes, and only if the interface is implemented

Given a class and attributes, I would like to use reflection to get the implemented interfaces and the annotate methods that have attributes applied.

In the below class, ITopicNotificationHandler<CommandRequested> and ITopicNotificationHandler<CommandUpdated> are implemented and marked.

The method Task Handle(SomeOtherPoco notification, string topic, CancellationToken cancellationToken) is marked with an attribute but not implemented as an interface on the class.

public class CommandRequestedEventHandler : ITopicNotificationHandler<CommandRequested>, ITopicNotificationHandler<CommandUpdated>
{
    [BusSubscription("{\"symbol\": [\"TVIX\"],\"timespan\": [\"1s\"]}")]
    [BusSubscription("{\"symbol\": [\"MSFT\"],\"timespan\": [\"1s\"]}")]
    public Task Handle(CommandRequested notification, string topic, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    [BusSubscription("{\"symbol\": [\"OTHER\"],\"timespan\": [\"1s\"]}")]
    public Task Handle(SomeOtherPoco notification, string topic, CancellationToken cancellationToken)
    {
        // this is not implemented as an interface, and should ignored
        return Task.CompletedTask;
    }

    [BusSubscription("{\"symbol\": [\"TVIX\"],\"timespan\": [\"1s\"]}")]
    public Task Handle(CommandUpdated notification, string topic, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

As per Find methods that have custom attribute using reflection I can get the methods:

var methods = assembly.GetTypes()
                  .SelectMany(t => t.GetMethods())
                  .Where(m => m.GetCustomAttributes(typeof(MenuItemAttribute), false).Length > 0)
                  .ToArray();

However, since i do container registration and other tasks based on scanning for implemented interfaces (of type ITopicNotificationHandler), as important that the method is marked with [BusSubscription] attribute, it should only be considered valid if it is implemented in the interface list of the class.

Would i get the list of methods then check the interface is implemented, or would one get the list of interfaces then check the method and read the attribute?

Essentially i would need the function below, but I am unsure of the best way and appreciate any pointers:

IEnumerable<BusSubscriptionAttribute> subscriptions = GetSubscriptionAttributes(typeof(ComamndHandler));




Aucun commentaire:

Enregistrer un commentaire