2008-11-08 4 views
2

Если я аннотирую метод класса с атрибутом, я могу затем получить пользовательские атрибуты для этого класса и посмотреть, есть ли у него этот атрибут. Например, я создаю сообщение-ориентированную программу, так у меня есть классы, какИзвлечение аннотированного метода из конструктора атрибутов

public class ErrorHandler 
{ 
    [HandleMessage(ErrorHandling.ERROR)] 
    private static void OnError(string message, object context, params object[] args) 
    { 
    Exception e; 
    args.Extract(out e); 

    Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace); 
    } 
} 

Во время выполнения я могу это сделать:

public static void RegisterStaticHandlers(Type type) 
{ 
    foreach (var mInfo in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)) 
    { 
    var mAttr = mInfo.GetCustomAttribute<HandleMessageAttribute>(); 
    if (mAttr != null) 
     RegisterInstanceHandler(mAttr.Message, mInfo.CreateDelegate<MessageHandler>()); 
    } 
} 

(у меня есть некоторые методы расширения для упрощения кода, они теперь не актуально.)

Мой вопрос: могу ли я избавиться от этого метода RegisterStaticHandlers и зарегистрировать обработчик в конструкторе атрибутов?

public class HandleMessageAttribute : Attribute 
{ 
    public string Message { get; private set; } 

    public HandleMessageAttribute(string message) 
    { 
    Message = message; 

    Messages.RegisterInstanceHandler(message, ... method reference here ...); 
    } 
} 

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

[Изменено] Я просто понял, что я могу по крайней мере, сделать это в статическом конструкторе:

static ErrorHandler() 
{ 
    Messages.RegisterStaticHandlers(typeof(ErrorHandler)); 
} 

Это, по крайней мере, сохраняет регистрацию класса внутри этого класса, который является большим, насколько я 'm related :)

ответ

3

Короче говоря, вы не можете сделать это из конструктора атрибутов. Когда атрибут сконструирован, он не имеет доступа к целевому методу/классу/полю/etc, к которому он применяется.

Из кода, я предполагаю, что вы хотите, чтобы код автоматически регистрировался при запуске? Один из способов сделать это может заключаться в том, чтобы исследовать вашу сборку (один раз, при запуске) - перечислить все классы (foreach(Type type in assembly)), найти те, у которых есть обработчики ошибок. Это уменьшает нагрузку на обслуживание. Другим вариантом будет что-то подобное с использованием файла конфигурации.

+0

Да, я на самом деле делаю это в Main() (я играю в консольном приложении), я просто подумал, что может быть способ избавиться от всего этого. Я новичок в атрибутах :) – 2008-11-08 09:19:00

Смежные вопросы