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);
}
}
- La question la plus intéressante est qui DI conteneur utilisez-vous?
Vous devez vous connecter pour publier un commentaire.
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 lorsque quelqu'un crée une 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-pattern.
</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
ToString()
décide de ce que vous cherchez. Comme un exemple pour la taille de segment de mémoire:Puis de le brancher en cours de démarrage:
LogManager
sont déjà un wrapper, ils ont juste arriver à être construit dans le cadre de log4net de l'assemblée. log4net est vrai de la surface est dans leConfigurator
,Repository
,Logger
,Appender
etFormatter
types, et vous ne devriez pas avoir de couplage, sauf dans votreApp.config
.ILog
avec le mode recommandé de l'utiliser est une meilleure conception de toute la maison wrapper j'ai jamais vu. Ce n'est pas que je suis intrinsèquement opposés à l'enrobage log4net, c'est que dans mon expérience, le remède est pire que la maladie.ILog
. Séparer le lot de wrapper dans sa propre assemblée, si vous devez, mais penser à long et dur avant d'écrire un nouveau.ILog
etLogManager
t couple vous pour le reste de log4net, car il vous oblige à avoir unusing log4net
dans votre code, et de disposer d'une référence à log4net.dll.log4net.ILog
etSomeStd.ILog
peuvent avoir le même nom de base et des membres, mais ils sont, néanmoins, les deux classes différentes.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.
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.
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)
et juste constructeur-injecter ILog chaque fois que vous en avez besoin.
Component.For<ILog>().UsingFactoryMethod((kernel, model, cc) => LogManager.GetLogger(cc.Handler.ComponentModel.Implementation))