Created
November 19, 2012 10:04
-
-
Save orient-man/4109938 to your computer and use it in GitHub Desktop.
Interceptor for managing database connection life cycle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using Castle.DynamicProxy; | |
namespace MyCompany.Infrastructure | |
{ | |
class CloseConnectionInterceptor : IInterceptor | |
{ | |
private static readonly MethodInfo ProxyGenericIteratorMethod = | |
typeof(CloseConnectionInterceptor) | |
.GetMethod( | |
"ProxyGenericIterator", | |
BindingFlags.NonPublic | BindingFlags.Static); | |
public void Intercept(IInvocation invocation) | |
{ | |
var returnType = invocation.Method.ReturnType; | |
if (returnType == typeof(IEnumerable)) | |
{ | |
HandleNonGenericIteratorInvocation(invocation); | |
} | |
else if (returnType.IsGenericType && | |
returnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) | |
{ | |
HandleGenericIteratorInvocation(invocation); | |
} | |
else | |
{ | |
HandleNormalInvocation(invocation); | |
} | |
} | |
private static void HandleNonGenericIteratorInvocation(IInvocation invocation) | |
{ | |
invocation.Proceed(); | |
invocation.ReturnValue = ProxyNonGenericIterator( | |
invocation.InvocationTarget, | |
invocation.ReturnValue as IEnumerable); | |
} | |
private static void HandleGenericIteratorInvocation(IInvocation invocation) | |
{ | |
invocation.Proceed(); | |
var method = ProxyGenericIteratorMethod.MakeGenericMethod( | |
invocation.Method.ReturnType.GetGenericArguments()[0]); | |
invocation.ReturnValue = method.Invoke( | |
null, | |
new[] { invocation.InvocationTarget, invocation.ReturnValue }); | |
} | |
private static IEnumerable<T> ProxyGenericIterator<T>( | |
object target, IEnumerable enumerable) | |
{ | |
return ProxyNonGenericIterator(target, enumerable).Cast<T>(); | |
} | |
private static IEnumerable ProxyNonGenericIterator( | |
object target, IEnumerable enumerable) | |
{ | |
try | |
{ | |
foreach (var element in enumerable) | |
yield return element; | |
} | |
finally | |
{ | |
CloseConnection(target); | |
} | |
} | |
private static void HandleNormalInvocation(IInvocation invocation) | |
{ | |
try | |
{ | |
invocation.Proceed(); | |
} | |
finally | |
{ | |
CloseConnection(invocation.InvocationTarget); | |
} | |
} | |
private static void CloseConnection(object target) | |
{ | |
// ... | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment