Как получить метаинформацию о методе в атрибуте метода?

#c# #reflection #attributes

Вопрос:

Как получить метаинформацию о методе в атрибуте метода ?

Я обычно избегаю необходимости записывать имя события как в атрибуте, так и в параметрах метода.

Для имени одного свойства имя(Тип) может быть приемлемым, но для других сквозных задач его просто недостаточно.

Существует множество сквозных проблем, которые нуждаются в этом-это всего лишь один пример:

  // From
        [SubscribeToEvent(nameof(SomeEventType))]
        public async Task SomeEventTypeEndpoint(SomeEventType someEvent)
        { (...) }
 // To
        [SubscribeToEvent]
        public async Task SomeEventTypeEndpoint(SomeEventType someEvent)
        { (...) }
 
 // From
    [AttributeUsage(AttributeTargets.Method)]
    public class SubscribeToEventAttribute : TopicAttribute
    {
        public SubscribeToEventAttribute(string eventName) 
        {
           // Do: log name, analytics, ect...
        }
    }
// To
    [AttributeUsage(AttributeTargets.Method)]
    public class SubscribeToEventAttribute : TopicAttribute
    {
        public SubscribeToEventAttribute() 
        {
           // Some reflection on what this attribute is applied to ?
           // Getting something like System.Reflection.ParameterInfo
           // Do: log name, analytics, ect...
        }
    }

 

Некоторые люди

Ответ №1:

Это невозможно сделать внутри конструктора атрибутов. Вам нужно будет использовать отражение, чтобы найти методы, определяющие атрибут.

Поэтому, чтобы найти все методы в классе , которые определяют атрибут, скажем SubscribeToEventAttribute , в классе, вы можете сделать что-то вроде этого:

 public static void CheckForSubscribeToEventAttributes(Type type) {
    var methods = type.GetMethods();
    for (int i = 0; i < methods.Length; i  ) {
        MethodInfo method = methods[i];
        if (method.IsDefined(typeof(SubscribeToEventAttribute))) {
            // Do something with the method ...
        }
    }
}
 

Если вы хотите получить фактические экземпляры атрибутов (а не просто проверить, существует ли атрибут), вы можете использовать MemberInfo.GetCustomAttributes . На самом деле конструкторы атрибутов не запускаются до тех пор, пока вы не вызовете этот метод.