zoukankan      html  css  js  c++  java
  • 关于《NHibernate中使用NLog》中在App.config(web.config)中增加nhibernatelogger节点的疑惑

    在上一篇《NHibernate中使用NLog》中最后在App.config或web.config中AppSettings节中增加nhibernate-logger节点的介绍比较含糊,引起了朋友的疑问,现在在这里关于这个节点进行详细的讲解。
    首先我们先看一下NH3的源码:NHibernate-3.1.0.GA/src/NHibernate/Logging.cs
    在该代码中获取AppSetttings节的配置节点的部门,如果它没有检测到用户的程序中配置了自定义的Log框架情况时则检测LOG4NET是否存在,如果存在则使用LOG4NET来记录LOG。另外NH3中也提供了LOG4NET的实现,可以看出NH3中对于LOG4NET的实现非常的灵活,我准备在下一篇文章中根据NH3中对于LOG4NET的实现方式来实现NLOG框架而不是象NHibernate中使用NLog中入门的方式来实现接口。
    using System;
    using System.Configuration;
    using System.IO;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace NHibernate
    {
    	public interface IInternalLogger
    	{
    		bool IsErrorEnabled { get; }
    		bool IsFatalEnabled { get; }
    		bool IsDebugEnabled { get; }
    		bool IsInfoEnabled { get; }
    		bool IsWarnEnabled { get; }
    		void Error(object message);
    		void Error(object message, Exception exception);
    		void ErrorFormat(string format, params object[] args);
    
    		void Fatal(object message);
    		void Fatal(object message, Exception exception);
    
    		void Debug(object message);
    		void Debug(object message, Exception exception);
    		void DebugFormat(string format, params object[] args);
    
    		void Info(object message);
    		void Info(object message, Exception exception);
    		void InfoFormat(string format, params object[] args);
    
    		void Warn(object message);
    		void Warn(object message, Exception exception);
    		void WarnFormat(string format, params object[] args);
    	}
    
    	public interface ILoggerFactory
    	{
    		IInternalLogger LoggerFor(string keyName);
    		IInternalLogger LoggerFor(System.Type type);
    	}
    
    	public class LoggerProvider
    	{
    		private const string NhibernateLoggerConfKey = "nhibernate-logger";
    		private readonly ILoggerFactory loggerFactory;
    		private static LoggerProvider instance;
    
    		static LoggerProvider()
    		{
    			string nhibernateLoggerClass = GetNhibernateLoggerClass();
    			ILoggerFactory loggerFactory = string.IsNullOrEmpty(nhibernateLoggerClass) ? new NoLoggingLoggerFactory() : GetLoggerFactory(nhibernateLoggerClass);
    			SetLoggersFactory(loggerFactory);
    		}
    
    		private static ILoggerFactory GetLoggerFactory(string nhibernateLoggerClass)
    		{
    			ILoggerFactory loggerFactory;
    			var loggerFactoryType = System.Type.GetType(nhibernateLoggerClass);
    			try
    			{
    				loggerFactory = (ILoggerFactory) Activator.CreateInstance(loggerFactoryType);
    			}
    			catch (MissingMethodException ex)
    			{
    				throw new ApplicationException("Public constructor was not found for " + loggerFactoryType, ex);
    			}
    			catch (InvalidCastException ex)
    			{
    				throw new ApplicationException(loggerFactoryType + "Type does not implement " + typeof (ILoggerFactory), ex);
    			}
    			catch (Exception ex)
    			{
    				throw new ApplicationException("Unable to instantiate: " + loggerFactoryType, ex);
    			}
    			return loggerFactory;
    		}
    
    		private static string GetNhibernateLoggerClass()
    		{
    			var nhibernateLogger = ConfigurationManager.AppSettings.Keys.Cast<string>().FirstOrDefault(k => NhibernateLoggerConfKey.Equals(k.ToLowerInvariant()));
    			string nhibernateLoggerClass = null;
    			if (string.IsNullOrEmpty(nhibernateLogger))
    			{
    				// look for log4net.dll
    				string baseDir = AppDomain.CurrentDomain.BaseDirectory;
    				string relativeSearchPath = AppDomain.CurrentDomain.RelativeSearchPath;
    				string binPath = relativeSearchPath == null ? baseDir : Path.Combine(baseDir, relativeSearchPath);
    				var log4NetDllPath = Path.Combine(binPath, "log4net.dll");
    
    				if (File.Exists(log4NetDllPath))
    				{
    					nhibernateLoggerClass = typeof (Log4NetLoggerFactory).AssemblyQualifiedName;
    				}
    			}
    			else
    			{
    				nhibernateLoggerClass = ConfigurationManager.AppSettings[nhibernateLogger];
    			}
    			return nhibernateLoggerClass;
    		}
    
    		public static void SetLoggersFactory(ILoggerFactory loggerFactory)
    		{
    			instance = new LoggerProvider(loggerFactory);
    		}
    
    		private LoggerProvider(ILoggerFactory loggerFactory)
    		{
    			this.loggerFactory = loggerFactory;
    		}
    
    		public static IInternalLogger LoggerFor(string keyName)
    		{
    			return instance.loggerFactory.LoggerFor(keyName);
    		}
    
    		public static IInternalLogger LoggerFor(System.Type type)
    		{
    			return instance.loggerFactory.LoggerFor(type);
    		}
    	}
    
    	public class NoLoggingLoggerFactory: ILoggerFactory
    	{
    		private static readonly IInternalLogger Nologging = new NoLoggingInternalLogger();
    		public IInternalLogger LoggerFor(string keyName)
    		{
    			return Nologging;
    		}
    
    		public IInternalLogger LoggerFor(System.Type type)
    		{
    			return Nologging;
    		}
    	}
    
    	public class NoLoggingInternalLogger: IInternalLogger
    	{
    		public bool IsErrorEnabled
    		{
    			get { return false;}
    		}
    
    		public bool IsFatalEnabled
    		{
    			get { return false; }
    		}
    
    		public bool IsDebugEnabled
    		{
    			get { return false; }
    		}
    
    		public bool IsInfoEnabled
    		{
    			get { return false; }
    		}
    
    		public bool IsWarnEnabled
    		{
    			get { return false; }
    		}
    
    		public void Error(object message)
    		{
    		}
    
    		public void Error(object message, Exception exception)
    		{
    		}
    
    		public void ErrorFormat(string format, params object[] args)
    		{
    		}
    
    		public void Fatal(object message)
    		{
    		}
    
    		public void Fatal(object message, Exception exception)
    		{
    		}
    
    		public void Debug(object message)
    		{
    		}
    
    		public void Debug(object message, Exception exception)
    		{
    		}
    
    		public void DebugFormat(string format, params object[] args)
    		{
    		}
    
    		public void Info(object message)
    		{
    		}
    
    		public void Info(object message, Exception exception)
    		{
    		}
    
    		public void InfoFormat(string format, params object[] args)
    		{
    		}
    
    		public void Warn(object message)
    		{
    		}
    
    		public void Warn(object message, Exception exception)
    		{
    		}
    
    		public void WarnFormat(string format, params object[] args)
    		{
    		}
    	}
    
    	public class Log4NetLoggerFactory: ILoggerFactory
    	{
    		private static readonly System.Type LogManagerType = System.Type.GetType("log4net.LogManager, log4net");
    		private static readonly Func<string, object> GetLoggerByNameDelegate;
    		private static readonly Func<System.Type, object> GetLoggerByTypeDelegate;
    		static Log4NetLoggerFactory()
    		{
    			GetLoggerByNameDelegate = GetGetLoggerMethodCall<string>();
    			GetLoggerByTypeDelegate = GetGetLoggerMethodCall<System.Type>();
    		}
    		public IInternalLogger LoggerFor(string keyName)
    		{
    			return new Log4NetLogger(GetLoggerByNameDelegate(keyName));
    		}
    
    		public IInternalLogger LoggerFor(System.Type type)
    		{
    			return new Log4NetLogger(GetLoggerByTypeDelegate(type));
    		}
    
    		private static Func<TParameter, object> GetGetLoggerMethodCall<TParameter>()
    		{
    			var method = LogManagerType.GetMethod("GetLogger", new[] { typeof(TParameter) });
    			ParameterExpression resultValue;
    			ParameterExpression keyParam = Expression.Parameter(typeof(TParameter), "key");
    			MethodCallExpression methodCall = Expression.Call(null, method, new Expression[] { resultValue = keyParam });
    			return Expression.Lambda<Func<TParameter, object>>(methodCall, new[] { resultValue }).Compile();
    		}
    	}
    
    	public class Log4NetLogger: IInternalLogger
    	{
    		private static readonly System.Type ILogType = System.Type.GetType("log4net.ILog, log4net");
    		private static readonly Func<object, bool> IsErrorEnabledDelegate;
    		private static readonly Func<object, bool> IsFatalEnabledDelegate;
    		private static readonly Func<object, bool> IsDebugEnabledDelegate;
    		private static readonly Func<object, bool> IsInfoEnabledDelegate;
    		private static readonly Func<object, bool> IsWarnEnabledDelegate;
    
    		private static readonly Action<object, object> ErrorDelegate;
    		private static readonly Action<object, object, Exception> ErrorExceptionDelegate;
    		private static readonly Action<object, string, object[]> ErrorFormatDelegate;
    
    		private static readonly Action<object, object> FatalDelegate;
    		private static readonly Action<object, object, Exception> FatalExceptionDelegate;
    
    		private static readonly Action<object, object> DebugDelegate;
    		private static readonly Action<object, object, Exception> DebugExceptionDelegate;
    		private static readonly Action<object, string, object[]> DebugFormatDelegate;
    
    		private static readonly Action<object, object> InfoDelegate;
    		private static readonly Action<object, object, Exception> InfoExceptionDelegate;
    		private static readonly Action<object, string, object[]> InfoFormatDelegate;
    
    		private static readonly Action<object, object> WarnDelegate;
    		private static readonly Action<object, object, Exception> WarnExceptionDelegate;
    		private static readonly Action<object, string, object[]> WarnFormatDelegate;
    
    		private readonly object logger;
    
    		static Log4NetLogger()
    		{
    			IsErrorEnabledDelegate = GetPropertyGetter("IsErrorEnabled");
    			IsFatalEnabledDelegate = GetPropertyGetter("IsFatalEnabled");
    			IsDebugEnabledDelegate = GetPropertyGetter("IsDebugEnabled");
    			IsInfoEnabledDelegate = GetPropertyGetter("IsInfoEnabled");
    			IsWarnEnabledDelegate = GetPropertyGetter("IsWarnEnabled");
    			ErrorDelegate = GetMethodCallForMessage("Error");
    			ErrorExceptionDelegate = GetMethodCallForMessageException("Error");
    			ErrorFormatDelegate = GetMethodCallForMessageFormat("ErrorFormat");
    
    			FatalDelegate = GetMethodCallForMessage("Fatal");
    			FatalExceptionDelegate = GetMethodCallForMessageException("Fatal");
    
    			DebugDelegate = GetMethodCallForMessage("Debug");
    			DebugExceptionDelegate = GetMethodCallForMessageException("Debug");
    			DebugFormatDelegate = GetMethodCallForMessageFormat("DebugFormat");
    
    			InfoDelegate = GetMethodCallForMessage("Info");
    			InfoExceptionDelegate = GetMethodCallForMessageException("Info");
    			InfoFormatDelegate = GetMethodCallForMessageFormat("InfoFormat");
    
    			WarnDelegate = GetMethodCallForMessage("Warn");
    			WarnExceptionDelegate = GetMethodCallForMessageException("Warn");
    			WarnFormatDelegate = GetMethodCallForMessageFormat("WarnFormat");
    		}
    
    		private static Func<object, bool> GetPropertyGetter(string propertyName)
    		{
    			ParameterExpression funcParam = Expression.Parameter(typeof(object), "l");
    			Expression convertedParam = Expression.Convert(funcParam, ILogType);
    			Expression property = Expression.Property(convertedParam, propertyName);
    			return (Func<object, bool>)Expression.Lambda(property, funcParam).Compile();
    		}
    
    		private static Action<object, object> GetMethodCallForMessage(string methodName)
    		{
    			ParameterExpression loggerParam = Expression.Parameter(typeof(object), "l");
    			ParameterExpression messageParam = Expression.Parameter(typeof(object), "o");
    			Expression convertedParam = Expression.Convert(loggerParam, ILogType);
    			MethodCallExpression methodCall = Expression.Call(convertedParam, ILogType.GetMethod(methodName, new[] { typeof(object) }), messageParam);
    			return (Action<object, object>)Expression.Lambda(methodCall, new[] { loggerParam, messageParam }).Compile();
    		}
    
    		private static Action<object, object, Exception> GetMethodCallForMessageException(string methodName)
    		{
    			ParameterExpression loggerParam = Expression.Parameter(typeof(object), "l");
    			ParameterExpression messageParam = Expression.Parameter(typeof(object), "o");
    			ParameterExpression exceptionParam = Expression.Parameter(typeof(Exception), "e");
    			Expression convertedParam = Expression.Convert(loggerParam, ILogType);
    			MethodCallExpression methodCall = Expression.Call(convertedParam, ILogType.GetMethod(methodName, new[] { typeof(object), typeof(Exception) }), messageParam, exceptionParam);
    			return (Action<object, object, Exception>)Expression.Lambda(methodCall, new[] { loggerParam, messageParam, exceptionParam }).Compile();
    		}
    
    		private static Action<object, string, object[]> GetMethodCallForMessageFormat(string methodName)
    		{
    			ParameterExpression loggerParam = Expression.Parameter(typeof(object), "l");
    			ParameterExpression formatParam = Expression.Parameter(typeof(string), "f");
    			ParameterExpression parametersParam = Expression.Parameter(typeof(object[]), "p");
    			Expression convertedParam = Expression.Convert(loggerParam, ILogType);
    			MethodCallExpression methodCall = Expression.Call(convertedParam, ILogType.GetMethod(methodName, new[] { typeof(string), typeof(object[]) }), formatParam, parametersParam);
    			return (Action<object, string, object[]>)Expression.Lambda(methodCall, new[] { loggerParam, formatParam, parametersParam }).Compile();
    		}
    
    		public Log4NetLogger(object logger)
    		{
    			this.logger = logger;
    		}
    
    		public bool IsErrorEnabled
    		{
    			get { return IsErrorEnabledDelegate(logger); }
    		}
    
    		public bool IsFatalEnabled
    		{
    			get { return IsFatalEnabledDelegate(logger); }
    		}
    
    		public bool IsDebugEnabled
    		{
    			get { return IsDebugEnabledDelegate(logger); }
    		}
    
    		public bool IsInfoEnabled
    		{
    			get { return IsInfoEnabledDelegate(logger); }
    		}
    
    		public bool IsWarnEnabled
    		{
    			get { return IsWarnEnabledDelegate(logger); }
    		}
    
    		public void Error(object message)
    		{
    			ErrorDelegate(logger, message);
    		}
    
    		public void Error(object message, Exception exception)
    		{
    			ErrorExceptionDelegate(logger,message,exception);
    		}
    
    		public void ErrorFormat(string format, params object[] args)
    		{
    			ErrorFormatDelegate(logger, format, args);
    		}
    
    		public void Fatal(object message)
    		{
    			FatalDelegate(logger, message);
    		}
    
    		public void Fatal(object message, Exception exception)
    		{
    			FatalExceptionDelegate(logger,message,exception);
    		}
    
    		public void Debug(object message)
    		{
    			DebugDelegate(logger, message);
    		}
    
    		public void Debug(object message, Exception exception)
    		{
    			DebugExceptionDelegate(logger, message, exception);
    		}
    
    		public void DebugFormat(string format, params object[] args)
    		{
    			DebugFormatDelegate(logger, format, args);
    		}
    
    		public void Info(object message)
    		{
    			InfoDelegate(logger, message);
    		}
    
    		public void Info(object message, Exception exception)
    		{
    			InfoExceptionDelegate(logger, message, exception);
    		}
    
    		public void InfoFormat(string format, params object[] args)
    		{
    			InfoFormatDelegate(logger, format, args);
    		}
    
    		public void Warn(object message)
    		{
    			WarnDelegate(logger, message);
    		}
    
    		public void Warn(object message, Exception exception)
    		{
    			WarnExceptionDelegate(logger, message, exception);
    		}
    
    		public void WarnFormat(string format, params object[] args)
    		{
    			WarnFormatDelegate(logger, format, args);
    		}
    	}
    }
    
  • 相关阅读:
    关于换位思考
    C# 4.0 新特性之参数
    短信猫和短信网关
    win7中cookies位置(IE)
    IIS6.0应用程序池回收和工作进程
    深入理解IIS工作原理
    IIS的启动与停止命令
    汉字和Unicode码(utf8)之间的转换(Pack/Unpack)
    用struct模块处理二进制数据
    python: string的操作函数
  • 原文地址:https://www.cnblogs.com/biyusoft/p/3432067.html
Copyright © 2011-2022 走看看