argumento log4net para LogManager.GetLogger

98

Por que a maioria dos exemplos de log4net obtém o registrador de uma classe fazendo isso:

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

Em vez de apenas passar typeof (MyClass):

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

Existe algum outro motivo para fazer isso, além do fato de que a primeira opção não exige que você digite um nome de classe específico?

Andy White
fonte

Respostas:

93

Acho que você tem o motivo. Eu faço isso dessa forma para que não precise me preocupar com o nome da classe e possa apenas copiar e colar o código padrão em uma nova classe.

Para obter a resposta oficial, consulte: Como faço para obter o nome totalmente qualificado de uma classe em um bloco estático? no log4net faq

Steven Lyons
fonte
Ok, ficou claro, obrigado por esse link, eu não tinha visto isso antes
Andy White
Isso é o mais antigo possível, mas dê uma olhada na minha resposta caso você ainda cole isso como código de caldeira :)
Noctis
Você economiza um pouquinho do tempo do Dev cortando e colando esse código. No entanto, há um custo para chamar 'GetCurrentMethod ()' em vez de usar uma constante de string ou chamar 'typeof ()'. Se você somar quantas vezes isso será chamado durante a vida útil do código em relação ao tempo que levará para digitar o nome da classe, acho que você está apenas desacelerando seu código para obter poucos benefícios.
Jovens
1
Você não está desacelerando tanto quanto pensa, esta é uma chamada estática, então você tem uma invocação por classe por domínio de aplicativo, por exemplo, se você tiver 300 classes, terá no máximo 300 chamadas para o tempo de vida de seu aplicativo
Paul Hatcher
Não faz sentido usar reflexão para obter o nome do tipo, e copiar / passado é preguiça e você obtém um impacto no desempenho, então por que não obter apenas o nome ?!
MeTitus de
8

Sou um usuário NLog e geralmente isso se resume a:

var _logger = LogManager.GetCurrentClassLogger();

Pareceu um pouco estranho que você precise passar por reflexão no Log4Net, então eu dei uma olhada no código-fonte do NLog e, vejam só, isso é o que eles fazem por você:

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

Acho que escreveria algo semelhante para Log4Net como uma extensão ou método estático em vez de colar o reflexo como parte do meu código de caldeira :)

Noctis
fonte
7

Como você disse - é conveniente porque você pode criar um logger em um método sem saber o nome da classe (trivial, eu sei), mas permite que você recorte e cole métodos entre as classes sem ter que renomear a chamada.

Preet Sangha
fonte
3

Acho que o motivo é que você obtém o tipo do tipo de tempo de execução usando o .DeclaringType()método. Você pode usar o logger em uma classe base e ainda ver o tipo real de seu objeto na saída dos loggers. Isso torna as investigações muito mais convenientes.

PeterB
fonte
0

Também torna mais fácil criar modelos Codesmith para fins de geração de código.

Phillip H. Blanton
fonte