From ad6b06b42c565b17488211a3fb185117d757da29 Mon Sep 17 00:00:00 2001 From: Dominique Schuppli Date: Sat, 30 Jan 2021 22:54:10 +0100 Subject: [PATCH] Skip interceptors for non-intercepted methods --- .../ClassProxyWithTargetTargetContributor.cs | 23 ++++++++++++++----- .../MethodWithInvocationGenerator.cs | 16 +++++++++---- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/Castle.Core/DynamicProxy/Contributors/ClassProxyWithTargetTargetContributor.cs b/src/Castle.Core/DynamicProxy/Contributors/ClassProxyWithTargetTargetContributor.cs index 73c6dfe348..5bcf512d11 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/ClassProxyWithTargetTargetContributor.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/ClassProxyWithTargetTargetContributor.cs @@ -60,14 +60,23 @@ protected override IEnumerable CollectElementsToProxyInternal( return null; } - if (IsDirectlyAccessible(method) == false) + var methodIsDirectlyAccessible = IsDirectlyAccessible(method); + + if (!method.Proxyable) { - return IndirectlyCalledMethodGenerator(method, @class, overrideMethod); + if (methodIsDirectlyAccessible) + { + return new ForwardingMethodGenerator(method, overrideMethod, (c, m) => c.GetField("__target")); + } + else + { + return IndirectlyCalledMethodGenerator(method, @class, overrideMethod, skipInterceptors: true); + } } - if (!method.Proxyable) + if (!methodIsDirectlyAccessible) { - return new ForwardingMethodGenerator(method, overrideMethod, (c, m) => c.GetField("__target")); + return IndirectlyCalledMethodGenerator(method, @class, overrideMethod); } var invocation = GetInvocationType(method, @class); @@ -140,7 +149,8 @@ private Type GetInvocationType(MetaMethod method, ClassEmitter @class) } private MethodGenerator IndirectlyCalledMethodGenerator(MetaMethod method, ClassEmitter proxy, - OverrideMethodDelegate overrideMethod) + OverrideMethodDelegate overrideMethod, + bool skipInterceptors = false) { var @delegate = GetDelegateType(method, proxy); var contributor = GetContributor(@delegate, method); @@ -148,9 +158,10 @@ private Type GetInvocationType(MetaMethod method, ClassEmitter @class) .Generate(proxy, namingScope) .BuildType(); return new MethodWithInvocationGenerator(method, - proxy.GetField("__interceptors"), + skipInterceptors ? NullExpression.Instance : proxy.GetField("__interceptors").ToExpression(), invocation, (c, m) => c.GetField("__target").ToExpression(), + null, overrideMethod, contributor); } diff --git a/src/Castle.Core/DynamicProxy/Generators/MethodWithInvocationGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/MethodWithInvocationGenerator.cs index 27d05eaf4f..7b5f7cf3da 100644 --- a/src/Castle.Core/DynamicProxy/Generators/MethodWithInvocationGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/MethodWithInvocationGenerator.cs @@ -34,13 +34,13 @@ internal class MethodWithInvocationGenerator : MethodGenerator private readonly IInvocationCreationContributor contributor; private readonly GetTargetExpressionDelegate getTargetExpression; private readonly GetTargetExpressionDelegate getTargetTypeExpression; - private readonly Reference interceptors; + private readonly Expression interceptors; private readonly Type invocation; public MethodWithInvocationGenerator(MetaMethod method, Reference interceptors, Type invocation, GetTargetExpressionDelegate getTargetExpression, OverrideMethodDelegate createMethod, IInvocationCreationContributor contributor) - : this(method, interceptors, invocation, getTargetExpression, null, createMethod, contributor) + : this(method, interceptors.ToExpression(), invocation, getTargetExpression, null, createMethod, contributor) { } @@ -48,6 +48,14 @@ internal class MethodWithInvocationGenerator : MethodGenerator GetTargetExpressionDelegate getTargetExpression, GetTargetExpressionDelegate getTargetTypeExpression, OverrideMethodDelegate createMethod, IInvocationCreationContributor contributor) + : this(method, interceptors.ToExpression(), invocation, getTargetExpression, getTargetTypeExpression, createMethod, contributor) + { + } + + public MethodWithInvocationGenerator(MetaMethod method, Expression interceptors, Type invocation, + GetTargetExpressionDelegate getTargetExpression, + GetTargetExpressionDelegate getTargetTypeExpression, + OverrideMethodDelegate createMethod, IInvocationCreationContributor contributor) : base(method, createMethod) { this.invocation = invocation; @@ -182,7 +190,7 @@ private Expression SetMethodInterceptors(ClassEmitter @class, INamingScope namin var emptyInterceptors = new NewArrayExpression(0, typeof(IInterceptor)); var selectInterceptors = new MethodInvocationExpression(selector, InterceptorSelectorMethods.SelectInterceptors, targetTypeExpression, - proxiedMethodTokenExpression, interceptors.ToExpression()) + proxiedMethodTokenExpression, interceptors) { VirtualCall = true }; emitter.CodeBuilder.AddExpression( @@ -218,7 +226,7 @@ private Expression[] GetCtorArguments(ClassEmitter @class, Expression proxiedMet { getTargetExpression(@class, MethodToOverride), SelfReference.Self.ToExpression(), - methodInterceptors ?? interceptors.ToExpression(), + methodInterceptors ?? interceptors, proxiedMethodTokenExpression, new ReferencesToObjectArrayExpression(dereferencedArguments) };