diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f32091ed3..a34e7bd401 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Bugfixes: - Proxying certain `[Serializable]` classes produces proxy types that fail PEVerify test (@stakx, #367) - `private protected` methods are not intercepted (@CrispyDrone, #535) - `System.UIntPtr` unsupported (@stakx, #546) +- DynamicProxy generates two modules when proceeding from a class proxy's protected method to the target, causing an `InvalidOperationException` when saving the generated assembly to disk (@stakx, #569) Deprecations: - Removed support for the .NET Framework < 4.5 and .NET Standard 1.x. (@stakx, #495, #496) diff --git a/src/Castle.Core.Tests.WeakNamed/DynamicProxy.Tests/ClassProxyWithTargetTestCase.cs b/src/Castle.Core.Tests.WeakNamed/DynamicProxy.Tests/ClassProxyWithTargetTestCase.cs new file mode 100644 index 0000000000..2d4f8d3fb8 --- /dev/null +++ b/src/Castle.Core.Tests.WeakNamed/DynamicProxy.Tests/ClassProxyWithTargetTestCase.cs @@ -0,0 +1,42 @@ +// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.DynamicProxy.Tests +{ + using NUnit.Framework; + + [TestFixture] + public class ClassProxyWithTargetTestCase : BasePEVerifyTestCase + { + [Test] + public void Forwards_to_protected_method() + { + var proxy = generator.CreateClassProxyWithTarget(new ClassWithProtectedMethod()); + Assert.AreEqual(42, proxy.InvokeFortyTwo()); + } + + public class ClassWithProtectedMethod + { + public int InvokeFortyTwo() + { + return FortyTwo(); + } + + protected virtual int FortyTwo() + { + return 42; + } + } + } +} diff --git a/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs index 11db73f2ac..8efd6d40cf 100644 --- a/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs @@ -78,7 +78,8 @@ private AbstractTypeEmitter GetEmitter(ClassEmitter @class, INamingScope namingS uniqueName, typeof(MulticastDelegate), Type.EmptyTypes, - DelegateFlags); + DelegateFlags, + forceUnsigned: @class.InStrongNamedModule == false); @delegate.CopyGenericParametersFromMethod(method.Method); return @delegate; } diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs index 4a428c8880..cb2023bc87 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs @@ -34,12 +34,6 @@ public ClassEmitter(ModuleScope modulescope, string name, Type baseType, IEnumer { } - public ClassEmitter(ModuleScope modulescope, string name, Type baseType, IEnumerable interfaces, - TypeAttributes flags) - : this(modulescope, name, baseType, interfaces, flags, forceUnsigned: false) - { - } - public ClassEmitter(ModuleScope modulescope, string name, Type baseType, IEnumerable interfaces, TypeAttributes flags, bool forceUnsigned)