1
1
using System ;
2
2
using System . Data . Common ;
3
+ using System . Linq . Expressions ;
3
4
using System . Reflection ;
4
5
using NHibernate . Util ;
5
6
@@ -86,18 +87,18 @@ protected static class PoolHelper<T> where T : IDriver
86
87
{
87
88
// Static field in generic class => one field per concrete type used. This is exactly what
88
89
// we need here, do not move the generic argument to the method. Otherwise it will cache the
89
- // method info of the first driver type used, and reuse it for other driver types, which
90
+ // delegate of the first driver type used, and reuse it for other driver types, which
90
91
// would fail.
91
- private static volatile MethodInfo _clearPool ;
92
- private static volatile MethodInfo _clearAllPools ;
92
+ private static volatile System . Action < DbConnection > _clearPool ;
93
+ private static volatile System . Action _clearAllPools ;
93
94
94
95
/// <summary>
95
96
/// Clears the connection pool.
96
97
/// </summary>
97
98
/// <param name="driver">The driver for which the connection pool has to be cleared.</param>
98
99
/// <param name="connectionString">The connection string of connections for which to clear the pool.
99
100
/// <c>null</c> for clearing them all.</param>
100
- internal static void ClearPool ( T driver , string connectionString )
101
+ public static void ClearPool ( T driver , string connectionString )
101
102
{
102
103
// In case of concurrent threads, may initialize many times. We do not care.
103
104
// Members are volatile for avoiding they get used while their constructor is not yet ended.
@@ -106,8 +107,14 @@ internal static void ClearPool(T driver, string connectionString)
106
107
using ( var clearConnection = driver . CreateConnection ( ) )
107
108
{
108
109
var connectionType = clearConnection . GetType ( ) ;
109
- _clearPool = connectionType . GetMethod ( "ClearPool" ) ?? throw new InvalidOperationException ( "Unable to resolve ClearPool method." ) ;
110
- _clearAllPools = connectionType . GetMethod ( "ClearAllPools" ) ?? throw new InvalidOperationException ( "Unable to resolve ClearAllPools method." ) ;
110
+
111
+ var clearPoolMethodInfo = GetMethod ( connectionType , "ClearPool" ) ;
112
+ var parameter = Expression . Parameter ( typeof ( DbConnection ) ) ;
113
+ var methodCall = Expression . Call ( clearPoolMethodInfo , Expression . Convert ( parameter , connectionType ) ) ;
114
+ _clearPool = Expression . Lambda < Action < DbConnection > > ( methodCall , parameter ) . Compile ( ) ;
115
+
116
+ var clearAllPoolsMethodInfo = GetMethod ( connectionType , "ClearAllPools" ) ;
117
+ _clearAllPools = ( System . Action ) Delegate . CreateDelegate ( typeof ( System . Action ) , clearAllPoolsMethodInfo ) ;
111
118
}
112
119
}
113
120
@@ -116,12 +123,17 @@ internal static void ClearPool(T driver, string connectionString)
116
123
using ( var clearConnection = driver . CreateConnection ( ) )
117
124
{
118
125
clearConnection . ConnectionString = connectionString ;
119
- _clearPool . Invoke ( null , new object [ ] { clearConnection } ) ;
126
+ _clearPool ( clearConnection ) ;
120
127
}
121
128
return ;
122
129
}
123
130
124
- _clearAllPools . Invoke ( null , Array . Empty < object > ( ) ) ;
131
+ _clearAllPools ( ) ;
132
+ }
133
+
134
+ private static MethodInfo GetMethod ( System . Type type , string methodName )
135
+ {
136
+ return type . GetMethod ( methodName ) ?? throw new InvalidOperationException ( $ "Unable to resolve { type . Name } .{ methodName } method.") ;
125
137
}
126
138
}
127
139
}
0 commit comments