Skip to content

Commit 6324a1c

Browse files
authored
fix issue 166 (#181)
1 parent c21b5fc commit 6324a1c

4 files changed

Lines changed: 85 additions & 2 deletions

File tree

core/src/AspectCore.Abstractions/DynamicProxy/ServiceInterceptorAttribute.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using System;
22
using System.Reflection;
3+
using System.Runtime;
34
using System.Threading.Tasks;
45

56
namespace AspectCore.DynamicProxy
67
{
7-
public sealed class ServiceInterceptorAttribute : AbstractInterceptorAttribute
8+
public sealed class ServiceInterceptorAttribute : AbstractInterceptorAttribute, IEquatable<ServiceInterceptorAttribute>
89
{
910
private readonly Type _interceptorType;
1011

@@ -16,6 +17,7 @@ public ServiceInterceptorAttribute(Type interceptorType)
1617
{
1718
throw new ArgumentNullException(nameof(interceptorType));
1819
}
20+
1921
if (!typeof(IInterceptor).GetTypeInfo().IsAssignableFrom(interceptorType.GetTypeInfo()))
2022
{
2123
throw new ArgumentException($"{interceptorType} is not an interceptor.", nameof(interceptorType));
@@ -31,7 +33,28 @@ public override Task Invoke(AspectContext context, AspectDelegate next)
3133
{
3234
throw new InvalidOperationException($"Cannot resolve type '{_interceptorType}' of service interceptor.");
3335
}
36+
3437
return instance.Invoke(context, next);
3538
}
39+
40+
public bool Equals(ServiceInterceptorAttribute other)
41+
{
42+
if (other == null)
43+
{
44+
return false;
45+
}
46+
return _interceptorType == other._interceptorType;
47+
}
48+
49+
public override bool Equals(object obj)
50+
{
51+
var other = obj as ServiceInterceptorAttribute;
52+
return Equals(other);
53+
}
54+
55+
public override int GetHashCode()
56+
{
57+
return _interceptorType.GetHashCode();
58+
}
3659
}
3760
}

core/src/AspectCore.Core/DynamicProxy/AttributeAdditionalInterceptorSelector.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,23 @@ public sealed class AttributeAdditionalInterceptorSelector : IAdditionalIntercep
1010
{
1111
public IEnumerable<IInterceptor> Select(MethodInfo serviceMethod, MethodInfo implementationMethod)
1212
{
13+
if (serviceMethod == implementationMethod)
14+
{
15+
yield break;
16+
}
17+
1318
foreach (var attribute in implementationMethod.DeclaringType.GetTypeInfo().GetReflector().GetCustomAttributes())
1419
{
1520
if (attribute is IInterceptor interceptor)
1621
yield return interceptor;
1722
}
23+
1824
foreach (var attribute in implementationMethod.GetReflector().GetCustomAttributes())
1925
{
2026
if (attribute is IInterceptor interceptor)
2127
yield return interceptor;
2228
}
29+
2330
if (!serviceMethod.DeclaringType.GetTypeInfo().IsClass)
2431
{
2532
foreach (var interceptor in SelectFromBase(implementationMethod))
@@ -36,6 +43,7 @@ private IEnumerable<IInterceptor> SelectFromBase(MethodInfo implementationMethod
3643
{
3744
return interceptors;
3845
}
46+
3947
var baseMethod = baseType.GetTypeInfo().GetMethodBySignature(new MethodSignature(implementationMethod));
4048
if (baseMethod != null)
4149
{
@@ -44,13 +52,16 @@ private IEnumerable<IInterceptor> SelectFromBase(MethodInfo implementationMethod
4452
if (attribute is IInterceptor interceptor && interceptor.Inherited)
4553
interceptors.Add(interceptor);
4654
}
55+
4756
foreach (var attribute in baseMethod.GetReflector().GetCustomAttributes())
4857
{
4958
if (attribute is IInterceptor interceptor && interceptor.Inherited)
5059
interceptors.Add(interceptor);
5160
}
61+
5262
interceptors.AddRange(SelectFromBase(baseMethod).Where(x => x.Inherited));
5363
}
64+
5465
return interceptors;
5566
}
5667
}

core/src/AspectCore.Core/DynamicProxy/InterceptorCollector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public IEnumerable<IInterceptor> Collect(MethodInfo serviceMethod, MethodInfo im
6060
return HandleInjector(CollectFromService(serviceMethod).
6161
Concat(CollectFromAdditionalSelector(serviceMethod, implementationMethod)).
6262
HandleSort().
63-
HandleMultiple()).ToArray();
63+
HandleMultiple()).Distinct().ToArray();
6464
});
6565
}
6666

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System.Threading.Tasks;
2+
using AspectCore.Configuration;
3+
using AspectCore.DynamicProxy;
4+
using AspectCore.Injector;
5+
using Xunit;
6+
7+
namespace AspectCore.Tests.Integrate
8+
{
9+
public class ServiceInterceptorTests : IntegrateTestBase
10+
{
11+
[Fact]
12+
public void Service_Interceptor_Tests()
13+
{
14+
var service = ServiceResolver.Resolve<IProxyTransient>();
15+
Assert.Equal(1, service.Foo());
16+
}
17+
18+
protected override void ConfigureService(IServiceContainer serviceContainer)
19+
{
20+
serviceContainer.AddType<Test>();
21+
serviceContainer.AddType<IProxyTransient,ProxyTransient>();
22+
}
23+
24+
public class Test : AbstractInterceptor
25+
{
26+
public override async Task Invoke(AspectContext context, AspectDelegate next)
27+
{
28+
await next(context);
29+
var val = (int) context.ReturnValue;
30+
context.ReturnValue = val + 1;
31+
}
32+
}
33+
34+
[ServiceInterceptor(typeof(Test))]
35+
public interface IProxyTransient
36+
{
37+
int Foo();
38+
}
39+
40+
[ServiceInterceptor(typeof(Test))]
41+
public class ProxyTransient : IProxyTransient
42+
{
43+
public virtual int Foo()
44+
{
45+
return 0;
46+
}
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)