argumen log4net ke LogManager.GetLogger

98

Mengapa sebagian besar contoh log4net mendapatkan logger untuk kelas dengan melakukan ini:

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

Daripada hanya meneruskan typeof (MyClass):

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

Apakah ada alasan lain untuk melakukan ini, selain fakta bahwa opsi pertama tidak mengharuskan Anda mengetik nama kelas tertentu?

Andy White
sumber

Jawaban:

93

Saya pikir Anda punya alasannya. Saya melakukannya dengan cara itu jadi saya tidak perlu khawatir tentang nama kelas dan cukup salin dan tempel kode pelat boiler di kelas baru.

Untuk jawaban resmi, lihat: Bagaimana cara mendapatkan nama kelas yang sepenuhnya memenuhi syarat dalam blok statis? di faq log4net

Steven Lyons
sumber
Ok itu menyelesaikannya, terima kasih untuk tautan itu, saya belum pernah melihatnya sebelumnya
Andy White
Ini sudah tua, tapi lihat jawaban saya jika Anda masih menempelkannya sebagai kode boiler :)
Noctis
Anda menghemat sedikit waktu Dev untuk memotong dan menempelkan kode ini. Namun ada biaya untuk memanggil 'GetCurrentMethod ()' dibandingkan menggunakan konstanta string atau memanggil 'typeof ()'. Jika Anda menambahkan berapa kali ini akan dipanggil selama masa pakai kode terhadap berapa lama Anda akan mengetikkan nama kelas, saya pikir Anda hanya memperlambat kode Anda untuk sedikit keuntungan.
Youngs
1
Anda tidak melambat sebanyak yang Anda pikirkan, ini adalah panggilan statis sehingga Anda memiliki satu pemanggilan per kelas per domain aplikasi, misalnya jika Anda memiliki 300 kelas, Anda memiliki paling banyak 300 panggilan untuk ini selama masa pakai aplikasi Anda
Paul Hatcher
Tidak ada gunanya menggunakan refleksi untuk mendapatkan nama tipe, dan salinan / masa lampau adalah kemalasan dan Anda mendapatkan performa yang bagus, jadi mengapa tidak mendapatkan namanya saja ?!
MeTitus
8

Saya adalah pengguna NLog, dan biasanya intinya adalah:

var _logger = LogManager.GetCurrentClassLogger();

Tampaknya agak aneh bahwa Anda perlu melakukan refleksi di Log4Net, jadi saya melihat kode sumber NLog, dan lihatlah, inilah yang mereka lakukan untuk Anda:

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

Saya kira saya akan menulis sesuatu yang serupa untuk Log4Net sebagai ekstensi atau metode statis daripada menempelkan refleksi sebagai bagian dari kode boiler saya :)

Noctis
sumber
7

Seperti yang Anda katakan - nyaman karena Anda dapat membuat logger dalam metode tanpa mengetahui nama kelas (sepele saya tahu) tetapi memungkinkan Anda untuk memotong dan menempelkan metode antar kelas tanpa harus mengganti nama panggilan.

Preet Sangha
sumber
3

Saya pikir alasannya adalah, bahwa Anda mendapatkan jenis tipe runtime menggunakan .DeclaringType()metode ini. Anda dapat menggunakan pencatat di kelas dasar dan masih melihat jenis objek Anda yang sebenarnya di keluaran pencatat. Itu membuat penyelidikan jauh lebih nyaman.

PeterB
sumber
0

Ini juga mempermudah pembuatan template Codesmith untuk tujuan pembuatan kode.

Phillip H. Blanton
sumber