Argument log4net à LogManager.GetLogger

98

Pourquoi la plupart des exemples de log4net obtiennent-ils le logger d'une classe en faisant ceci:

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

Plutôt que de simplement passer typeof (MyClass):

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

Y a-t-il une autre raison de faire cela, outre le fait que la première option ne vous oblige pas à taper un nom de classe spécifique?

Andy White
la source

Réponses:

93

Je pense que tu as la raison. Je le fais de cette façon pour ne pas avoir à me soucier du nom de la classe et je peux simplement copier et coller le code de la plaque de chaudière dans une nouvelle classe.

Pour obtenir la réponse officielle, voir: Comment obtenir le nom complet d'une classe dans un bloc statique? à la FAQ de log4net

Steven Lyons
la source
Ok ça clarifie les choses, merci pour ce lien, je n'avais jamais vu ça avant
Andy White
C'est aussi vieux que possible, mais jetez un œil à ma réponse au cas où vous collez toujours cela comme code de chaudière :)
Noctis
Vous économisez un peu de temps aux développeurs en coupant et en collant ce code. Cependant, il y a un coût à appeler 'GetCurrentMethod ()' au lieu d'utiliser une constante de chaîne ou d'appeler 'typeof ()'. Si vous additionnez le nombre de fois que cela sera appelé pendant la durée de vie du code par rapport au temps qu'il vous faudra pour taper le nom de la classe, je pense que vous ralentissez simplement votre code pour peu d'avantages.
Youngs
1
Vous ne ralentissez pas autant que vous le pensez, il s'agit d'un appel statique, vous avez donc une invocation par classe et par domaine d'application, par exemple si vous avez 300 classes, vous avez au plus 300 appels pour la durée de vie de votre application
Paul Hatcher
Il n'y a aucun intérêt à utiliser la réflexion pour obtenir le nom du type, et le copier / coller est de la paresse et vous obtenez un coup de performance, alors pourquoi ne pas obtenir simplement le nom?!
MeTitus
8

Je suis un utilisateur de NLog, et cela se résume généralement à:

var _logger = LogManager.GetCurrentClassLogger();

Il m'a semblé un peu étrange que vous ayez besoin de réfléchir dans Log4Net, j'ai donc jeté un coup d'œil dans le code source de NLog, et voilà, voici ce qu'ils font pour vous:

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

Je suppose que j'écrirais quelque chose de similaire pour Log4Net en tant qu'extension ou méthode statique au lieu de coller la réflexion dans le cadre de mon code de chaudière :)

Noctis
la source
7

Comme vous le dites - c'est pratique car vous pouvez créer un enregistreur dans une méthode sans connaître le nom de la classe (trivial je sais) mais vous permet de couper et coller des méthodes entre les classes sans avoir à renommer l'appel.

Preet Sangha
la source
3

Je pense que la raison est que vous obtenez le type du type d'exécution à l'aide de la .DeclaringType()méthode. Vous pouvez utiliser l'enregistreur dans une classe de base et toujours voir le type réel de votre objet dans la sortie des enregistreurs. Cela rend les enquêtes beaucoup plus pratiques.

PeterB
la source
0

Cela facilite également la création de modèles Codesmith à des fins de génération de code.

Phillip H. Blanton
la source