argumento log4net para LogManager.GetLogger

98

¿Por qué la mayoría de los ejemplos de log4net obtienen el registrador para una clase haciendo esto?

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

En lugar de simplemente pasar typeof (MyClass):

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

¿Hay alguna otra razón para hacer esto, además del hecho de que la primera opción no requiere que escriba un nombre de clase específico?

Andy White
fuente

Respuestas:

93

Creo que tienes la razón. Lo hago de esa manera para no tener que preocuparme por el nombre de la clase y simplemente puedo copiar y pegar el código de la placa de la caldera en una nueva clase.

Para obtener la respuesta oficial, consulte: ¿Cómo obtengo el nombre completo de una clase en un bloque estático? en las preguntas frecuentes de log4net

Steven Lyons
fuente
Ok, eso lo aclara, gracias por ese enlace, no lo había visto antes
Andy White
Esto es tan antiguo como parece, pero eche un vistazo a mi respuesta en caso de que aún lo pegue como código de caldera :)
Noctis
Ahorras un poquito de tiempo de desarrollo cortando y pegando este código. Sin embargo, hay un costo para llamar a 'GetCurrentMethod ()' en lugar de usar una constante de cadena o llamar a 'typeof ()'. Si suma cuántas veces se llamará a esto durante la vida útil del código en comparación con el tiempo que le llevará escribir el nombre de la clase, creo que solo está ralentizando su código para obtener pocos beneficios.
Youngs
1
No está disminuyendo la velocidad tanto como cree, esta es una llamada estática, por lo que tiene una invocación por clase por dominio de aplicación, por ejemplo, si tiene 300 clases, tiene como máximo 300 llamadas a esto durante la vida útil de su aplicación
Paul Hatcher
No tiene sentido usar la reflexión para obtener el nombre del tipo, y la copia / pasado es la pereza y obtienes un éxito en el rendimiento, así que ¿por qué no obtener solo el nombre?
MeTitus
8

Soy un usuario de NLog y, por lo general, esto se reduce a:

var _logger = LogManager.GetCurrentClassLogger();

Parecía un poco extraño que debas pasar por la reflexión en Log4Net, así que eché un vistazo al código fuente de NLog, y he aquí, esto es lo que hacen por ti:

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

Supongo que escribiría algo similar para Log4Net como una extensión o método estático en lugar de pegar el reflejo como parte de mi código de caldera :)

Noctis
fuente
7

Como usted dice, es conveniente ya que puede crear un registrador en un método sin saber el nombre de la clase (trivial, lo sé), pero le permite cortar y pegar métodos entre clases sin tener que cambiar el nombre de la llamada.

Preet Sangha
fuente
3

Creo que la razón es que obtienes el tipo de tipo de tiempo de ejecución usando el .DeclaringType()método. Puede usar el registrador en una clase base y aún ver el tipo real de su objeto en la salida del registrador. Eso hace que las investigaciones sean mucho más convenientes.

PeterB
fuente
0

También facilita la creación de plantillas de Codesmith con fines de generación de código.

Phillip H. Blanton
fuente