log4net argument do LogManager.GetLogger

98

Dlaczego większość przykładów log4net pobiera rejestrator dla klasy, wykonując następujące czynności:

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

Zamiast tylko przekazywać typeof (MyClass):

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

Czy jest jakiś inny powód, aby to zrobić, poza tym, że pierwsza opcja nie wymaga podania określonej nazwy klasy?

Andy White
źródło

Odpowiedzi:

93

Myślę, że masz powód. Robię to w ten sposób, więc nie muszę się martwić o nazwę klasy i mogę po prostu skopiować i wkleić kod płyty kotłowej w nowej klasie.

Aby uzyskać oficjalną odpowiedź, zobacz: Jak uzyskać w pełni kwalifikowaną nazwę klasy w bloku statycznym? w log4net FAQ

Steven Lyons
źródło
Ok, to wyjaśnia sprawę, dzięki za ten link, nie widziałem tego wcześniej
Andy White
To jest tak stare, jak to tylko możliwe, ale spójrz na moją odpowiedź na wypadek, gdybyś nadal wklejał to jako kod kotła :)
Noctis
Zaoszczędzisz trochę czasu Dev na wycinaniu i wklejaniu tego kodu. Jednak wywołanie „GetCurrentMethod ()” wiąże się z kosztami w przeciwieństwie do używania stałej łańcuchowej lub wywoływania „typeof ()”. Jeśli dodasz, ile razy będzie to wywoływane przez cały okres istnienia kodu, w porównaniu z tym, jak długo zajmie ci wpisanie nazwy klasy, myślę, że po prostu spowalniasz kod, aby uzyskać niewielką korzyść.
Youngs
1
Nie zwalniasz tak bardzo, jak myślisz, jest to wywołanie statyczne, więc masz jedno wywołanie na klasę na domenę aplikacji, np. Jeśli masz 300 klas, masz maksymalnie 300 wywołań do tego przez cały okres istnienia aplikacji
Paul Hatcher
Nie ma sensu używać refleksji, aby uzyskać nazwę typu, a kopia / przeszłość to lenistwo i dostajesz hit wydajności, więc dlaczego nie zdobyć tylko nazwy ?!
MeTitus
8

Jestem użytkownikiem NLog i zwykle sprowadza się to do:

var _logger = LogManager.GetCurrentClassLogger();

Wydawało się trochę dziwne, że musisz przejść przez refleksję w Log4Net, więc zajrzałem do kodu źródłowego NLog i oto, co robią dla ciebie:

[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);
}

Chyba napisałbym coś podobnego dla Log4Net jako rozszerzenie lub metoda statyczna zamiast wklejać odbicie jako część kodu mojego kotła :)

Noctis
źródło
7

Jak mówisz - jest to wygodne, ponieważ możesz stworzyć logger w metodzie bez znajomości nazwy klasy (wiem, trywialne), ale pozwala na wycinanie i wklejanie metod między klasami bez konieczności zmiany nazwy wywołania.

Preet Sangha
źródło
3

Myślę, że powodem jest to, że za pomocą .DeclaringType()metody otrzymujesz typ typu środowiska uruchomieniowego . Możesz użyć programu rejestrującego w klasie bazowej i nadal widzieć rzeczywisty typ obiektu w danych wyjściowych programu rejestrującego. To sprawia, że ​​dochodzenia są znacznie wygodniejsze.

PeterB
źródło
0

Ułatwia również tworzenie szablonów Codesmith do celów generowania kodu.

Phillip H. Blanton
źródło