аргумент log4net для LogManager.GetLogger

98

Почему большинство примеров log4net получают регистратор для класса следующим образом:

private static ILog logger = 
    LogManager.GetLogger(
    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Вместо того, чтобы просто передавать typeof (MyClass):

private static ILog logger = LogManager.GetLogger(typeof(MyClass));

Есть ли какие-либо другие причины для этого, помимо того факта, что первый вариант не требует, чтобы вы вводили конкретное имя класса?

Энди Уайт
источник

Ответы:

93

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

Официальный ответ см. В разделе: Как получить полное имя класса в статическом блоке? в часто задаваемых вопросах log4net

Стивен Лайонс
источник
Хорошо, это проясняет, спасибо за эту ссылку, я не видел этого раньше
Энди Уайт
Это настолько стара, насколько возможно, но взгляните на мой ответ, если вы все еще вставляете его как код котла :)
Ноктис
Вы сэкономите немного времени разработчика, вырезая и вставив этот код. Однако вызов GetCurrentMethod () стоит дорого, в отличие от использования строковой константы или вызова typeof (). Если вы сложите, сколько раз это будет вызываться за время жизни кода, против того, сколько времени вам понадобится, чтобы ввести имя класса, я думаю, что вы просто замедляете свой код с небольшой пользой.
Янгс
1
Вы не замедляетесь так сильно, как думаете, это статический вызов, поэтому у вас есть один вызов для каждого класса для каждого домена приложения, например, если у вас есть 300 классов, у вас есть не более 300 вызовов для этого за время существования вашего приложения
Пол Hatcher
Нет смысла использовать отражение для получения имени типа, а копирование / прошлое - это лень, и вы получаете удар производительности, так почему бы не получить только имя ?!
MeTitus
8

Я пользователь NLog, и обычно это сводится к следующему:

var _logger = LogManager.GetCurrentClassLogger();

Мне показалось немного странным, что вам нужно пройти рефлексию в Log4Net, поэтому я взглянул на исходный код NLog и, о чудо, вот что они для вас делают:

[MethodImpl(MethodImplOptions.NoInlining)]
public static Logger GetCurrentClassLogger()
{
    string loggerName;
    Type declaringType;
    int framesToSkip = 1;
    do
    {
#if SILVERLIGHT
        StackFrame frame = new StackTrace().GetFrame(framesToSkip);
#else
        StackFrame frame = new StackFrame(framesToSkip, false);
#endif
        var method = frame.GetMethod();
        declaringType = method.DeclaringType;
        if (declaringType == null)
        {
            loggerName = method.Name;
            break;
        }
        framesToSkip++;
        loggerName = declaringType.FullName;
    } while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase));
    return globalFactory.GetLogger(loggerName);
}

Думаю, я бы написал что-то подобное для Log4Net как расширение или статический метод вместо того, чтобы вставлять отражение как часть моего кода котла :)

Ноктис
источник
7

Как вы говорите - это удобно, поскольку вы можете создать регистратор в методе, не зная имени класса (я знаю тривиально), но позволяет вырезать и вставлять методы между классами без необходимости переименовывать вызов.

Preet Sangha
источник
3

Я думаю, причина в том, что с помощью .DeclaringType()метода вы получаете тип времени выполнения . Вы можете использовать регистратор в базовом классе и по-прежнему видеть фактический тип вашего объекта в выходных данных регистратора. Это делает расследования намного удобнее.

PeterB
источник
0

Это также упрощает создание шаблонов Codesmith для целей генерации кода.

Филип Х. Блэнтон
источник