11using System ;
2+ using System . Linq ;
23using System . Linq . Expressions ;
34using System . Reflection ;
45using NHibernate . Util ;
@@ -12,16 +13,48 @@ namespace NHibernate
1213 public class Log4NetLoggerFactory : ILoggerFactory
1314#pragma warning restore 618
1415 {
15- private static readonly System . Type LogManagerType = System . Type . GetType ( "log4net.LogManager, log4net" ) ;
16+ internal static readonly Assembly Log4NetAssembly ;
17+ private static readonly System . Type LogManagerType ;
1618 private static readonly Func < Assembly , string , object > GetLoggerByNameDelegate ;
1719 private static readonly Func < System . Type , object > GetLoggerByTypeDelegate ;
1820
1921 static Log4NetLoggerFactory ( )
2022 {
23+ LogManagerType = GetLogManagerType ( ) ;
24+ if ( LogManagerType == null )
25+ return ;
26+
27+ Log4NetAssembly = LogManagerType . Assembly ;
2128 GetLoggerByNameDelegate = GetGetLoggerByNameMethodCall ( ) ;
2229 GetLoggerByTypeDelegate = GetGetLoggerMethodCall < System . Type > ( ) ;
2330 }
2431
32+ public Log4NetLoggerFactory ( )
33+ {
34+ if ( LogManagerType == null )
35+ throw new TypeLoadException ( "Cannot find log4net.LogManager type" ) ;
36+ }
37+
38+ // Code adapted from ReflectHelper.TypeFromAssembly, which cannot be called directly due
39+ // to depending on the logger.
40+ private static System . Type GetLogManagerType ( )
41+ {
42+ var typeName = "log4net.LogManager, log4net" ;
43+ // Try to get the type from an already loaded assembly
44+ var type = System . Type . GetType ( typeName ) ;
45+ if ( type != null )
46+ return type ;
47+
48+ // Load type from an already loaded assembly, or yield null
49+ return System . Type . GetType (
50+ typeName ,
51+ // An alternate could be "a.GetName().Name == an.Name", but GetName() is not lightweight.
52+ // "a.FullName == an.FullName" can never match because an.FullName will lack the version, culture
53+ // and public key token.
54+ an => AppDomain . CurrentDomain . GetAssemblies ( ) . FirstOrDefault ( a => a . FullName . StartsWith ( "log4net," ) ) ,
55+ null ) ;
56+ }
57+
2558#pragma warning disable 618
2659 [ Obsolete ( "Use this as an INHibernateLoggerFactory instead." ) ]
2760 public IInternalLogger LoggerFor ( string keyName )
@@ -39,6 +72,8 @@ public IInternalLogger LoggerFor(System.Type type)
3972 private static Func < TParameter , object > GetGetLoggerMethodCall < TParameter > ( )
4073 {
4174 var method = LogManagerType . GetMethod ( "GetLogger" , new [ ] { typeof ( TParameter ) } ) ;
75+ if ( method == null )
76+ throw new InvalidOperationException ( $ "Unable to find LogManager.GetLogger({ typeof ( TParameter ) } )") ;
4277 ParameterExpression resultValue ;
4378 ParameterExpression keyParam = Expression . Parameter ( typeof ( TParameter ) , "key" ) ;
4479 MethodCallExpression methodCall = Expression . Call ( null , method , resultValue = keyParam ) ;
@@ -48,6 +83,8 @@ private static Func<TParameter, object> GetGetLoggerMethodCall<TParameter>()
4883 private static Func < Assembly , string , object > GetGetLoggerByNameMethodCall ( )
4984 {
5085 var method = LogManagerType . GetMethod ( "GetLogger" , new [ ] { typeof ( Assembly ) , typeof ( string ) } ) ;
86+ if ( method == null )
87+ throw new InvalidOperationException ( "Unable to find LogManager.GetLogger(Assembly, string)" ) ;
5188 ParameterExpression nameParam = Expression . Parameter ( typeof ( string ) , "name" ) ;
5289 ParameterExpression repositoryAssemblyParam = Expression . Parameter ( typeof ( Assembly ) , "repositoryAssembly" ) ;
5390 MethodCallExpression methodCall = Expression . Call ( null , method , repositoryAssemblyParam , nameParam ) ;
@@ -62,7 +99,6 @@ private static Func<Assembly, string, object> GetGetLoggerByNameMethodCall()
6299 public class Log4NetLogger : IInternalLogger
63100#pragma warning restore 618
64101 {
65- private static readonly System . Type ILogType = System . Type . GetType ( "log4net.ILog, log4net" ) ;
66102 private static readonly Func < object , bool > IsErrorEnabledDelegate ;
67103 private static readonly Func < object , bool > IsFatalEnabledDelegate ;
68104 private static readonly Func < object , bool > IsDebugEnabledDelegate ;
@@ -92,29 +128,35 @@ public class Log4NetLogger : IInternalLogger
92128
93129 static Log4NetLogger ( )
94130 {
95- IsErrorEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( ILogType , "IsErrorEnabled" ) ;
96- IsFatalEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( ILogType , "IsFatalEnabled" ) ;
97- IsDebugEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( ILogType , "IsDebugEnabled" ) ;
98- IsInfoEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( ILogType , "IsInfoEnabled" ) ;
99- IsWarnEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( ILogType , "IsWarnEnabled" ) ;
100- ErrorDelegate = DelegateHelper . BuildAction < object > ( ILogType , "Error" ) ;
101- ErrorExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( ILogType , "Error" ) ;
102- ErrorFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( ILogType , "ErrorFormat" ) ;
103-
104- FatalDelegate = DelegateHelper . BuildAction < object > ( ILogType , "Fatal" ) ;
105- FatalExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( ILogType , "Fatal" ) ;
106-
107- DebugDelegate = DelegateHelper . BuildAction < object > ( ILogType , "Debug" ) ;
108- DebugExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( ILogType , "Debug" ) ;
109- DebugFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( ILogType , "DebugFormat" ) ;
110-
111- InfoDelegate = DelegateHelper . BuildAction < object > ( ILogType , "Info" ) ;
112- InfoExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( ILogType , "Info" ) ;
113- InfoFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( ILogType , "InfoFormat" ) ;
114-
115- WarnDelegate = DelegateHelper . BuildAction < object > ( ILogType , "Warn" ) ;
116- WarnExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( ILogType , "Warn" ) ;
117- WarnFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( ILogType , "WarnFormat" ) ;
131+ if ( Log4NetLoggerFactory . Log4NetAssembly == null )
132+ throw new TypeLoadException (
133+ "Cannot load ILog type, log4net is not found" ) ;
134+
135+ var iLogType = Log4NetLoggerFactory . Log4NetAssembly . GetType ( "log4net.ILog" , true ) ;
136+
137+ IsErrorEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( iLogType , "IsErrorEnabled" ) ;
138+ IsFatalEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( iLogType , "IsFatalEnabled" ) ;
139+ IsDebugEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( iLogType , "IsDebugEnabled" ) ;
140+ IsInfoEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( iLogType , "IsInfoEnabled" ) ;
141+ IsWarnEnabledDelegate = DelegateHelper . BuildPropertyGetter < bool > ( iLogType , "IsWarnEnabled" ) ;
142+ ErrorDelegate = DelegateHelper . BuildAction < object > ( iLogType , "Error" ) ;
143+ ErrorExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( iLogType , "Error" ) ;
144+ ErrorFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( iLogType , "ErrorFormat" ) ;
145+
146+ FatalDelegate = DelegateHelper . BuildAction < object > ( iLogType , "Fatal" ) ;
147+ FatalExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( iLogType , "Fatal" ) ;
148+
149+ DebugDelegate = DelegateHelper . BuildAction < object > ( iLogType , "Debug" ) ;
150+ DebugExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( iLogType , "Debug" ) ;
151+ DebugFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( iLogType , "DebugFormat" ) ;
152+
153+ InfoDelegate = DelegateHelper . BuildAction < object > ( iLogType , "Info" ) ;
154+ InfoExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( iLogType , "Info" ) ;
155+ InfoFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( iLogType , "InfoFormat" ) ;
156+
157+ WarnDelegate = DelegateHelper . BuildAction < object > ( iLogType , "Warn" ) ;
158+ WarnExceptionDelegate = DelegateHelper . BuildAction < object , Exception > ( iLogType , "Warn" ) ;
159+ WarnFormatDelegate = DelegateHelper . BuildAction < string , object [ ] > ( iLogType , "WarnFormat" ) ;
118160 }
119161
120162 /// <summary>
0 commit comments