77 votes

Comment utiliser log4net avec l'Injection de Dépendance

Je suis à essayer de comprendre quelle est la bonne formulation et l'utilisation de log4net est avec une injection de dépendance cadre.

Log4Net utilise la ILog interface mais m'oblige à appeler

LogManager.GetLogger(Reflection.MethodBase.GetCurrentMethod().DeclaringType)

dans chaque classe ou d'une méthode où j'ai besoin d'un journal d'informations. Cela semble aller à l'encontre du Cio principes et les couples de moi à l'aide de Log4Net.

Dois-je en quelque sorte mis dans une autre couche d'abstraction quelque part?

Aussi, j'ai besoin de vous connecter propriétés personnalisées comme le nom d'utilisateur comme ceci:

log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;

Comment puis-je saisir cette sorte que je n'ai pas à vous rappeler de le faire à chaque fois et toujours conserver la méthode actuelle qui est de l'exploitation forestière. dois-je faire quelque chose comme cela ou suis-je totalement à côté de la plaque?

public static class Logger
{
    public static void LogException(Type declaringType, string message, Exception ex)
    {
        log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;
        ILog log = LogManager.GetLogger(declaringType);
        log.Error(message, ex);
    }
}

61voto

Jeffrey Hantin Points 19272

Je pense que vous n'êtes pas voir la forêt pour les arbres. ILog et LogManager sont à la légèreté de façade près de 1:1 équivalent à Apache commons-logging, et ne sont pas réellement en couple, votre code pour le reste de log4net.

<rant>
J'ai également constaté que presque toujours quand quelqu'un crée un MyCompanyLogger wrapper autour de log4net ils manquent le point de mal et perdra important et utile capacités du cadre, de jeter de l'information utile, de perdre les gains de performance possible, même en utilisant les simplifiée ILog interface, ou tout ce qui précède. En d'autres termes, emballage log4net pour éviter l'attelage est un anti-modèle.
</rant>

Si vous sentez le besoin de se l'injecter, faire de votre journal instance accessible via une propriété pour permettre l'injection, mais de créer une instance par défaut de la manière démodée.

Comme pour contextuels de l'état dans chaque message de log, vous devez ajouter une propriété globale dont l' ToString() décide de ce que vous cherchez. Comme un exemple pour la taille de segment de mémoire:

public class TotalMemoryProperty
{
	public override string ToString()
	{
		return GC.GetTotalMemory(false).ToString();
	}
}

Puis de le brancher en cours de démarrage:

GlobalContext.Properties["TotalMemory"] = new TotalMemoryProperty();

2voto

CSharpAtl Points 3867

Comment j'ai fait c'était de créer ma propre interface, et avait une classe implémente l'interface utilisée Log4Net, et injecté de cette classe. De cette façon, vous ne sont pas liés à Log4Net...il vous suffit de créer une autre classe pour une nouvelle enregistreur et injecter cette classe.

2voto

Dillie-O Points 16780

Si vous êtes vraiment préoccupés par le fait d'avoir plusieurs enregistreurs, vous pouvez toujours déclarer un mondial de l'enregistreur et l'appeler pour tous vos enregistrement. L'inconvénient de cette est que vous perdez le construit dans la capacité à identifier la classe que le journal a été émis, mais vous pouvez également injecter votre propre message personnalisé dans le journal pour identifier la classe.

Cela dépend de la façon robuste vous voulez que l'enregistrement de l'être. Vous pouvez également simplement mettre l'enregistreur de la classe principale et de laisser toutes les exceptions non gérées bulle jusqu'à elle pour la journalisation.

2voto

santos Points 86

Une autre façon de faire serait de câbler l'log4net ILog interface contenant la séquence d'enregistrement comme ceci: (à l'aide de Château dans un ASP.NET ci-dessous à titre d'exemple)

container.Register(Component.For<ILog>().LifeStyle
    .PerWebRequest.UsingFactoryMethod(() => LogManager.GetLogger(
    MethodBase.GetCurrentMethod().DeclaringType)));

et juste constructeur-injecter ILog chaque fois que vous en avez besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X