AbstractInvocation
using System;
using System.Reflection;
namespace Castle.DynamicProxy
{
public abstract class AbstractInvocation : IInvocation
{
private readonly IInterceptor[] interceptors;
private readonly object[] arguments;
private int currentInterceptorIndex = -1;
private Type[] genericMethodArguments;
private readonly MethodInfo proxiedMethod;
protected readonly object proxyObject;
public abstract object InvocationTarget { get; }
public abstract Type TargetType { get; }
public abstract MethodInfo MethodInvocationTarget { get; }
public Type[] GenericArguments => genericMethodArguments;
public object Proxy => proxyObject;
public MethodInfo Method => proxiedMethod;
public object ReturnValue { get; set; }
public object[] Arguments => arguments;
protected AbstractInvocation(object proxy, IInterceptor[] interceptors, MethodInfo proxiedMethod, object[] arguments)
{
proxyObject = proxy;
this.interceptors = interceptors;
this.proxiedMethod = proxiedMethod;
this.arguments = arguments;
}
public void SetGenericMethodArguments(Type[] arguments)
{
genericMethodArguments = arguments;
}
public MethodInfo GetConcreteMethod()
{
return EnsureClosedMethod(Method);
}
public MethodInfo GetConcreteMethodInvocationTarget()
{ get; }
public void SetArgumentValue(int index, object value)
{
arguments[index] = value;
}
public object GetArgumentValue(int index)
{
return arguments[index];
}
public void Proceed()
{
if (interceptors == null)
InvokeMethodOnTarget();
else {
currentInterceptorIndex++;
try {
if (currentInterceptorIndex == interceptors.Length)
InvokeMethodOnTarget();
else {
if (currentInterceptorIndex > interceptors.Length) {
string text = (interceptors.Length <= 1) ? " interceptor" : (" each one of " + interceptors.Length + " interceptors");
throw new InvalidOperationException("This is a DynamicProxy2 error: invocation.Proceed() has been called more times than expected.This usually signifies a bug in the calling code. Make sure that" + text + " selected for the method '" + Method + "'calls invocation.Proceed() at most once.");
}
interceptors[currentInterceptorIndex].Intercept(this);
}
} finally {
currentInterceptorIndex--;
}
}
}
protected abstract void InvokeMethodOnTarget();
protected void ThrowOnNoTarget()
{
string text = (interceptors.Length != 0) ? "The interceptor attempted to 'Proceed'" : "There are no interceptors specified";
string text2;
string text3;
if (Method.DeclaringType.GetTypeInfo().IsClass && Method.IsAbstract) {
text2 = "is abstract";
text3 = "an abstract method";
} else {
text2 = "has no target";
text3 = "method without target";
}
throw new NotImplementedException($"""{text}""{Method}""{text2}""{text3}""");
}
private MethodInfo EnsureClosedMethod(MethodInfo method)
{
if (method.ContainsGenericParameters)
return method.GetGenericMethodDefinition().MakeGenericMethod(genericMethodArguments);
return method;
}
}
}