| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- using System;
- using System.Reflection;
- using System.Threading.Tasks;
- using Abp.Threading;
- using Castle.DynamicProxy;
- namespace Abp.Domain.Uow
- {
- /// <summary>
- /// This interceptor is used to manage database connection and transactions.
- /// </summary>
- internal class UnitOfWorkInterceptor : IInterceptor
- {
- private readonly IUnitOfWorkManager _unitOfWorkManager;
- private readonly IUnitOfWorkDefaultOptions _unitOfWorkOptions;
- public UnitOfWorkInterceptor(IUnitOfWorkManager unitOfWorkManager, IUnitOfWorkDefaultOptions unitOfWorkOptions)
- {
- _unitOfWorkManager = unitOfWorkManager;
- _unitOfWorkOptions = unitOfWorkOptions;
- }
- /// <summary>
- /// Intercepts a method.
- /// </summary>
- /// <param name="invocation">Method invocation arguments</param>
- public void Intercept(IInvocation invocation)
- {
- MethodInfo method;
- try
- {
- method = invocation.MethodInvocationTarget;
- }
- catch
- {
- method = invocation.GetConcreteMethod();
- }
- var unitOfWorkAttr = _unitOfWorkOptions.GetUnitOfWorkAttributeOrNull(method);
- if (unitOfWorkAttr == null || unitOfWorkAttr.IsDisabled)
- {
- //No need to a uow
- invocation.Proceed();
- return;
- }
- //No current uow, run a new one
- PerformUow(invocation, unitOfWorkAttr.CreateOptions());
- }
- private void PerformUow(IInvocation invocation, UnitOfWorkOptions options)
- {
- if (invocation.Method.IsAsync())
- {
- PerformAsyncUow(invocation, options);
- }
- else
- {
- PerformSyncUow(invocation, options);
- }
- }
- private void PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options)
- {
- using (var uow = _unitOfWorkManager.Begin(options))
- {
- invocation.Proceed();
- uow.Complete();
- }
- }
- private void PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options)
- {
- var uow = _unitOfWorkManager.Begin(options);
- 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()
- );
- }
- }
- }
- }
|