mirror of https://github.com/abpframework/abp.git
6 changed files with 265 additions and 24 deletions
@ -0,0 +1,181 @@ |
|||||
|
using System; |
||||
|
using System.Reflection; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.Threading |
||||
|
{ |
||||
|
internal static class InternalAsyncHelper |
||||
|
{ |
||||
|
public static async Task AwaitTaskWithFinally(Task actualReturnValue, Action<Exception> finalAction) |
||||
|
{ |
||||
|
Exception exception = null; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
await actualReturnValue; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exception = ex; |
||||
|
throw; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
finalAction(exception); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static async Task AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func<Task> postAction, Action<Exception> finalAction) |
||||
|
{ |
||||
|
Exception exception = null; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
await actualReturnValue; |
||||
|
await postAction(); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exception = ex; |
||||
|
throw; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
finalAction(exception); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static async Task AwaitTaskWithPreActionAndPostActionAndFinally(Func<Task> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null) |
||||
|
{ |
||||
|
Exception exception = null; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
if (preAction != null) |
||||
|
{ |
||||
|
await preAction(); |
||||
|
} |
||||
|
|
||||
|
await actualReturnValue(); |
||||
|
|
||||
|
if (postAction != null) |
||||
|
{ |
||||
|
await postAction(); |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exception = ex; |
||||
|
throw; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
if (finalAction != null) |
||||
|
{ |
||||
|
finalAction(exception); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static async Task<T> AwaitTaskWithFinallyAndGetResult<T>(Task<T> actualReturnValue, Action<Exception> finalAction) |
||||
|
{ |
||||
|
Exception exception = null; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return await actualReturnValue; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exception = ex; |
||||
|
throw; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
finalAction(exception); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static object CallAwaitTaskWithFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Action<Exception> finalAction) |
||||
|
{ |
||||
|
return typeof(InternalAsyncHelper) |
||||
|
.GetTypeInfo() |
||||
|
.GetMethod("AwaitTaskWithFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) |
||||
|
.MakeGenericMethod(taskReturnType) |
||||
|
.Invoke(null, new object[] { actualReturnValue, finalAction }); |
||||
|
} |
||||
|
|
||||
|
public static async Task<T> AwaitTaskWithPostActionAndFinallyAndGetResult<T>(Task<T> actualReturnValue, Func<Task> postAction, Action<Exception> finalAction) |
||||
|
{ |
||||
|
Exception exception = null; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
var result = await actualReturnValue; |
||||
|
await postAction(); |
||||
|
return result; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exception = ex; |
||||
|
throw; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
finalAction(exception); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static object CallAwaitTaskWithPostActionAndFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Func<Task> action, Action<Exception> finalAction) |
||||
|
{ |
||||
|
return typeof (InternalAsyncHelper) |
||||
|
.GetTypeInfo() |
||||
|
.GetMethod("AwaitTaskWithPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) |
||||
|
.MakeGenericMethod(taskReturnType) |
||||
|
.Invoke(null, new object[] { actualReturnValue, action, finalAction }); |
||||
|
} |
||||
|
|
||||
|
public static async Task<T> AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult<T>(Func<Task<T>> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null) |
||||
|
{ |
||||
|
Exception exception = null; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
if (preAction != null) |
||||
|
{ |
||||
|
await preAction(); |
||||
|
} |
||||
|
|
||||
|
var result = await actualReturnValue(); |
||||
|
|
||||
|
if (postAction != null) |
||||
|
{ |
||||
|
await postAction(); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
exception = ex; |
||||
|
throw; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
if (finalAction != null) |
||||
|
{ |
||||
|
finalAction(exception); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static object CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(Type taskReturnType, Func<object> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null) |
||||
|
{ |
||||
|
return typeof(InternalAsyncHelper) |
||||
|
.GetTypeInfo() |
||||
|
.GetMethod("AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) |
||||
|
.MakeGenericMethod(taskReturnType) |
||||
|
.Invoke(null, new object[] { actualReturnValue, preAction, postAction, finalAction }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,13 +1,74 @@ |
|||||
using Volo.Abp.DynamicProxy; |
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DynamicProxy; |
||||
|
using Volo.Abp.Threading; |
||||
using Volo.DependencyInjection; |
using Volo.DependencyInjection; |
||||
|
|
||||
namespace Volo.Abp.Uow |
namespace Volo.Abp.Uow |
||||
{ |
{ |
||||
public class UnitOfWorkInterceptor : IAbpInterceptor, ITransientDependency |
public class UnitOfWorkInterceptor : IAbpInterceptor, ITransientDependency |
||||
{ |
{ |
||||
|
private readonly IUnitOfWorkManager _unitOfWorkManager; |
||||
|
|
||||
|
public UnitOfWorkInterceptor(IUnitOfWorkManager unitOfWorkManager) |
||||
|
{ |
||||
|
_unitOfWorkManager = unitOfWorkManager; |
||||
|
} |
||||
|
|
||||
|
|
||||
public void Intercept(IAbpMethodInvocation invocation) |
public void Intercept(IAbpMethodInvocation invocation) |
||||
{ |
{ |
||||
invocation.Proceed(); |
//TODO: Check UOW attribute and other conditions!
|
||||
|
|
||||
|
if (invocation.Method.IsAsync()) |
||||
|
{ |
||||
|
PerformAsyncUow(invocation); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
PerformSyncUow(invocation); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void PerformSyncUow(IAbpMethodInvocation invocation) |
||||
|
{ |
||||
|
using (var uow = _unitOfWorkManager.Begin()) |
||||
|
{ |
||||
|
invocation.Proceed(); |
||||
|
uow.Complete(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void PerformAsyncUow(IAbpMethodInvocation invocation) |
||||
|
{ |
||||
|
var uow = _unitOfWorkManager.Begin(); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
invocation.Proceed(); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
uow.Dispose(); |
||||
|
throw; |
||||
|
} |
||||
|
|
||||
|
if (invocation.Method.ReturnType == typeof(Task)) |
||||
|
{ |
||||
|
invocation.ReturnValue = InternalAsyncHelper.AwaitTaskWithPostActionAndFinally( |
||||
|
(Task)invocation.ReturnValue, |
||||
|
async () => await uow.CompleteAsync(), |
||||
|
exception => uow.Dispose() |
||||
|
); |
||||
|
} |
||||
|
else //Task<TResult>
|
||||
|
{ |
||||
|
invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult( |
||||
|
invocation.Method.ReturnType.GenericTypeArguments[0], |
||||
|
invocation.ReturnValue, |
||||
|
async () => await uow.CompleteAsync(), |
||||
|
exception => uow.Dispose() |
||||
|
); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue