protected virtual void AssertReturnTypeCombination(MethodInfo adapterMethod, MethodInfo targetMethod, InvocationTypes targetInvocationType) { Type targetMethodReturnType = targetMethod.ReturnType; switch (targetInvocationType) { case InvocationTypes.Sync: if (AdapterHelper.IsVoid(adapterMethod.ReturnType) && adapterMethod.ReturnType != targetMethodReturnType) { throw new AdapterInterceptorException($"Adapter and target method return types should match if either is void.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.GenericTask: if (!AdapterHelper.IsGenericTask(adapterMethod.ReturnType)) { throw new AdapterInterceptorException($"Adapter and target method return types should both be a generic Task.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.Task: if (adapterMethod.ReturnType != targetMethodReturnType) { throw new AdapterInterceptorException($"Adapter and target method return types should match if target return type is Task.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.GenericValueTask: if (!AdapterHelper.IsGenericValueTask(adapterMethod.ReturnType)) { throw new AdapterInterceptorException($"Adapter and target method return types should both be a generic ValueTask.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; case InvocationTypes.ValueTask: if (!AdapterHelper.IsValueTask(adapterMethod.ReturnType)) { throw new AdapterInterceptorException($"Adapter and target method return types should match if target return type is ValueTask.{Environment.NewLine}Adapter method: {adapterMethod.ToLoggerString()}{Environment.NewLine}Target method: {targetMethod.ToLoggerString()}"); } break; default: throw new NotImplementedException(); } }
protected virtual AdapterInvocationInformation PrepareAdapterInvocationInformation(MethodInfo adapterMethod, MethodInfo targetMethod, Type[] adapterMethodParameterTypes, Type[] targetMethodParmeterTypes) { Type targetMethodReturnType = targetMethod.ReturnType; // Task<> if (AdapterHelper.IsGenericTask(targetMethodReturnType)) { MethodInfo genericInvokeTargetGenericTaskAsyncMethod = _invokeTargetGenericTaskAsync_Method.MakeGenericMethod(adapterMethod.ReturnType.GenericTypeArguments[0]); InvocationTypes targetInvocationType = InvocationTypes.GenericTask; AssertReturnTypeCombination(adapterMethod, targetMethod, targetInvocationType); return(new AdapterInvocationInformation(targetMethod, adapterMethodParameterTypes, targetMethodParmeterTypes, targetInvocationType, genericInvokeTargetGenericTaskAsyncMethod)); } // Task else if (AdapterHelper.IsTask(targetMethodReturnType)) { InvocationTypes targetInvocationType = InvocationTypes.Task; AssertReturnTypeCombination(adapterMethod, targetMethod, targetInvocationType); return(new AdapterInvocationInformation(targetMethod, adapterMethodParameterTypes, targetMethodParmeterTypes, targetInvocationType)); } // ValueTask<> else if (AdapterHelper.IsGenericValueTask(targetMethodReturnType)) { MethodInfo genericInvokeTargetGenericValueTaskAsyncMethod = _invokeTargetGenericValueTaskAsync_Method.MakeGenericMethod(adapterMethod.ReturnType.GenericTypeArguments[0]); InvocationTypes targetInvocationType = InvocationTypes.GenericValueTask; AssertReturnTypeCombination(adapterMethod, targetMethod, targetInvocationType); return(new AdapterInvocationInformation(targetMethod, adapterMethodParameterTypes, targetMethodParmeterTypes, targetInvocationType, genericInvokeTargetGenericValueTaskAsyncMethod)); } // ValueTask else if (AdapterHelper.IsValueTask(targetMethodReturnType)) { InvocationTypes targetInvocationType = InvocationTypes.ValueTask; AssertReturnTypeCombination(adapterMethod, targetMethod, targetInvocationType); return(new AdapterInvocationInformation(targetMethod, adapterMethodParameterTypes, targetMethodParmeterTypes, targetInvocationType)); } else // Likely synchronous { InvocationTypes targetInvocationType = InvocationTypes.Sync; AssertReturnTypeCombination(adapterMethod, targetMethod, targetInvocationType); return(new AdapterInvocationInformation(targetMethod, adapterMethodParameterTypes, targetMethodParmeterTypes, targetInvocationType)); } }