Skip to content

Commit 19354eb

Browse files
committed
merge files
1 parent a92c665 commit 19354eb

File tree

3 files changed

+29
-41
lines changed

3 files changed

+29
-41
lines changed

src/AspectCore.Core/Utils/ProxyGeneratorUtils.CovariantReturnMethod.cs

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/AspectCore.Core/Utils/ProxyGeneratorUtils.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using System.Reflection;
88
using System.Reflection.Emit;
9+
using System.Runtime.CompilerServices;
910
using System.Threading;
1011
using System.Threading.Tasks;
1112
using AspectCore.DynamicProxy;
@@ -163,6 +164,29 @@ private Type CreateClassProxyInternal(string name, Type serviceType, Type implTy
163164
return typeDesc.Compile();
164165
}
165166

167+
// key: covariant return method
168+
// value: interface method declarations
169+
internal static IReadOnlyDictionary<MethodInfo, HashSet<MethodInfo>> GetCovariantReturnMethodMap(Type implType)
170+
{
171+
var result = new Dictionary<MethodInfo, HashSet<MethodInfo>>();
172+
// No PreserveBaseOverridesAttribute means that the runtime does not support covariant return types.
173+
if (AspectCore.Extensions.MethodInfoExtensions.PreserveBaseOverridesAttribute is null)
174+
return result;
175+
176+
var covariantReturnMethods = implType
177+
.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
178+
.Where(m => m.IsPreserveBaseOverride(true))
179+
.ToHashSet();
180+
181+
foreach (var method in covariantReturnMethods)
182+
{
183+
var interfaceDeclarations = method.GetInterfaceDeclarations().ToHashSet();
184+
result[method] = interfaceDeclarations;
185+
}
186+
187+
return result;
188+
}
189+
166190
private class ProxyNameUtils
167191
{
168192
private readonly Dictionary<string, ProxyNameIndex> _indexes = new Dictionary<string, ProxyNameIndex>();
@@ -461,7 +485,10 @@ internal static MethodBuilder DefineClassMethod(MethodInfo method, Type implType
461485
var methodBuilder = DefineMethod(method, method.Name, attributes, implType, typeDesc);
462486
return methodBuilder;
463487
}
464-
488+
489+
// NOTE: when a covariant return method is handling:
490+
// For class proxy: We just define the covariant return methods in the implementation type like normal methods, the CLR will handle the propagation. (in this case covariantReturnMethod is null)
491+
// For interface proxy: We need to use the covariant return methods as the interface methods' implementation. (in this case covariantReturnMethod is not null)
465492
private static MethodBuilder DefineMethod(MethodInfo method, string name, MethodAttributes attributes, Type implType, TypeDesc typeDesc, MethodInfo covariantReturnMethod = null)
466493
{
467494
var implementationMethod = covariantReturnMethod ?? implType.GetTypeInfo().GetMethodBySignature(method);

tests/AspectCore.Tests/DynamicProxy/CovariantReturnMethodTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void CreateClassProxy_CovariantReturnsService_DerivedCovariantReturnsServ
6767
Assert.Equal(nameof(DerivedCovariantReturnsService), service.Method());
6868
Assert.Equal(nameof(CovariantReturnsService), service.Property);
6969
}
70-
70+
7171
[Fact]
7272
public void CreateInterfaceProxy_IService_CovariantReturnsService_Test()
7373
{

0 commit comments

Comments
 (0)