98 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C#
		
	
	
using Castle.DynamicProxy;
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Linq;
 | 
						|
using System.Reflection;
 | 
						|
using System.Runtime.CompilerServices;
 | 
						|
using System.Text;
 | 
						|
using System.Threading.Tasks;
 | 
						|
 | 
						|
namespace IRaCIS.Core.Application.AOP
 | 
						|
{
 | 
						|
    public abstract class AsyncInterceptorBase : IInterceptor
 | 
						|
    {
 | 
						|
        public AsyncInterceptorBase()
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        public void Intercept(IInvocation invocation)
 | 
						|
        {
 | 
						|
            BeforeProceed(invocation);
 | 
						|
            invocation.Proceed();
 | 
						|
            if (IsAsyncMethod(invocation.MethodInvocationTarget))
 | 
						|
            {
 | 
						|
                invocation.ReturnValue = InterceptAsync((dynamic)invocation.ReturnValue, invocation);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                AfterProceedSync(invocation);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private bool CheckMethodReturnTypeIsTaskType(MethodInfo method)
 | 
						|
        {
 | 
						|
            var methodReturnType = method.ReturnType;
 | 
						|
            if (methodReturnType.IsGenericType)
 | 
						|
            {
 | 
						|
                if (methodReturnType.GetGenericTypeDefinition() == typeof(Task<>) ||
 | 
						|
                    methodReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>))
 | 
						|
                    return true;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (methodReturnType == typeof(Task) ||
 | 
						|
                    methodReturnType == typeof(ValueTask))
 | 
						|
                    return true;
 | 
						|
            }
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        private bool IsAsyncMethod(MethodInfo method)
 | 
						|
        {
 | 
						|
            bool isDefAsync = Attribute.IsDefined(method, typeof(AsyncStateMachineAttribute), false);
 | 
						|
            bool isTaskType = CheckMethodReturnTypeIsTaskType(method);
 | 
						|
            bool isAsync = isDefAsync && isTaskType;
 | 
						|
 | 
						|
            return isAsync;
 | 
						|
        }
 | 
						|
 | 
						|
        protected object ProceedAsyncResult { get; set; }
 | 
						|
 | 
						|
 | 
						|
        private async Task InterceptAsync(Task task, IInvocation invocation)
 | 
						|
        {
 | 
						|
            await task.ConfigureAwait(false);
 | 
						|
            await AfterProceedAsync(invocation, false);
 | 
						|
        }
 | 
						|
 | 
						|
        private async Task<TResult> InterceptAsync<TResult>(Task<TResult> task, IInvocation invocation)
 | 
						|
        {
 | 
						|
            ProceedAsyncResult = await task.ConfigureAwait(false);
 | 
						|
            await AfterProceedAsync(invocation, true);
 | 
						|
            return (TResult)ProceedAsyncResult;
 | 
						|
        }
 | 
						|
 | 
						|
        private async ValueTask InterceptAsync(ValueTask task, IInvocation invocation)
 | 
						|
        {
 | 
						|
            await task.ConfigureAwait(false);
 | 
						|
            await AfterProceedAsync(invocation, false);
 | 
						|
        }
 | 
						|
 | 
						|
        private async ValueTask<TResult> InterceptAsync<TResult>(ValueTask<TResult> task, IInvocation invocation)
 | 
						|
        {
 | 
						|
            ProceedAsyncResult = await task.ConfigureAwait(false);
 | 
						|
            await AfterProceedAsync(invocation, true);
 | 
						|
            return (TResult)ProceedAsyncResult;
 | 
						|
        }
 | 
						|
 | 
						|
        protected virtual void BeforeProceed(IInvocation invocation) { }
 | 
						|
 | 
						|
        protected virtual void AfterProceedSync(IInvocation invocation) { }
 | 
						|
 | 
						|
        protected virtual Task AfterProceedAsync(IInvocation invocation, bool hasAsynResult)
 | 
						|
        {
 | 
						|
            return Task.CompletedTask;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |