AbstractInvocation
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Castle.DynamicProxy
{
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Runtime.CompilerServices.Nullable(0)]
public abstract class AbstractInvocation : IInvocation
{
[System.Runtime.CompilerServices.NullableContext(0)]
private sealed class ProceedInfo : IInvocationProceedInfo
{
[System.Runtime.CompilerServices.Nullable(1)]
private readonly AbstractInvocation invocation;
private readonly int interceptorIndex;
[System.Runtime.CompilerServices.NullableContext(1)]
public ProceedInfo(AbstractInvocation invocation)
{
this.invocation = invocation;
interceptorIndex = invocation.currentInterceptorIndex;
}
public void Invoke()
{
int currentInterceptorIndex = invocation.currentInterceptorIndex;
try {
invocation.currentInterceptorIndex = interceptorIndex;
invocation.Proceed();
} finally {
invocation.currentInterceptorIndex = currentInterceptorIndex;
}
}
}
[System.Runtime.CompilerServices.Nullable(1)]
private readonly IInterceptor[] interceptors;
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
private readonly object[] arguments;
private int currentInterceptorIndex = -1;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
private Type[] genericMethodArguments;
[System.Runtime.CompilerServices.Nullable(1)]
private readonly MethodInfo proxiedMethod;
[System.Runtime.CompilerServices.Nullable(1)]
protected readonly object proxyObject;
public abstract object InvocationTarget { get; }
public abstract Type TargetType { get; }
public abstract MethodInfo MethodInvocationTarget { get; }
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
public Type[] GenericArguments {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
get {
return genericMethodArguments;
}
}
[System.Runtime.CompilerServices.Nullable(1)]
public object Proxy {
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return proxyObject;
}
}
[System.Runtime.CompilerServices.Nullable(1)]
public MethodInfo Method {
[System.Runtime.CompilerServices.NullableContext(1)]
get {
return proxiedMethod;
}
}
public object ReturnValue { get; set; }
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
public object[] Arguments {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
get {
return arguments;
}
}
[System.Runtime.CompilerServices.NullableContext(1)]
protected AbstractInvocation(object proxy, IInterceptor[] interceptors, MethodInfo proxiedMethod, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})] object[] arguments)
{
proxyObject = proxy;
this.interceptors = interceptors;
this.proxiedMethod = proxiedMethod;
this.arguments = arguments;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public void SetGenericMethodArguments(Type[] arguments)
{
genericMethodArguments = arguments;
}
[System.Runtime.CompilerServices.NullableContext(1)]
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)
throw new InvalidOperationException("Cannot proceed past the end of the interception pipeline. This likely signifies a bug in the calling code.");
interceptors[currentInterceptorIndex].Intercept(this);
}
} finally {
currentInterceptorIndex--;
}
}
}
[System.Runtime.CompilerServices.NullableContext(1)]
public IInvocationProceedInfo CaptureProceedInfo()
{
return new ProceedInfo(this);
}
protected abstract void InvokeMethodOnTarget();
[DoesNotReturn]
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.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}""");
}
[System.Runtime.CompilerServices.NullableContext(1)]
private MethodInfo EnsureClosedMethod(MethodInfo method)
{
if (method.ContainsGenericParameters)
return method.GetGenericMethodDefinition().MakeGenericMethod(genericMethodArguments);
return method;
}
}
}