Skip to content

Commit cd18440

Browse files
authored
Merge pull request #256 from dotnetcore/override
Override
2 parents aa56411 + 3a2c9da commit cd18440

File tree

10 files changed

+187
-221
lines changed

10 files changed

+187
-221
lines changed

WebApiClientCore.Analyzers/SourceGenerator/HttpApiProxyClass.cs

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -103,41 +103,32 @@ public override string ToString()
103103
builder.AppendLine();
104104

105105
var index = 0;
106-
foreach (var method in this.FindApiMethods())
106+
foreach (var interfaceType in this.httpApi.AllInterfaces.Append(httpApi))
107107
{
108-
var methodCode = this.BuildMethod(method, index);
109-
builder.AppendLine(methodCode);
110-
index += 1;
108+
foreach (var method in interfaceType.GetMembers().OfType<IMethodSymbol>())
109+
{
110+
var methodCode = this.BuildMethod(interfaceType, method, index);
111+
builder.AppendLine(methodCode);
112+
index += 1;
113+
}
111114
}
112115

116+
113117
builder.AppendLine("\t}");
114118
builder.AppendLine("}");
115119
builder.AppendLine("#pragma warning restore");
116120

117121
return builder.ToString();
118122
}
119123

120-
/// <summary>
121-
/// 查找接口类型及其继承的接口的所有方法
122-
/// </summary>
123-
/// <returns></returns>
124-
private IEnumerable<IMethodSymbol> FindApiMethods()
125-
{
126-
#pragma warning disable RS1024
127-
return this.httpApi.AllInterfaces.Append(httpApi)
128-
.SelectMany(item => item.GetMembers())
129-
.OfType<IMethodSymbol>()
130-
.Distinct(MethodEqualityComparer.Default);
131-
#pragma warning restore RS1024
132-
}
133-
134124
/// <summary>
135125
/// 构建方法
136126
/// </summary>
127+
/// <param name="interfaceType"></param>
137128
/// <param name="method"></param>
138129
/// <param name="index"></param>
139130
/// <returns></returns>
140-
private string BuildMethod(IMethodSymbol method, int index)
131+
private string BuildMethod(INamedTypeSymbol interfaceType, IMethodSymbol method, int index)
141132
{
142133
var builder = new StringBuilder();
143134
var parametersString = string.Join(",", method.Parameters.Select(item => $"{GetFullName(item.Type)} {item.Name}"));
@@ -146,9 +137,10 @@ private string BuildMethod(IMethodSymbol method, int index)
146137
? "global::System.Array.Empty<global::System.Object>()"
147138
: $"new global::System.Object[] {{ {parameterNamesString} }}";
148139

140+
var methodName = $"\"{interfaceType.ToDisplayString()}.{method.Name}\"";
149141
var returnTypeString = GetFullName(method.ReturnType);
150-
builder.AppendLine($"\t\t[global::WebApiClientCore.HttpApiProxyMethod({index})]");
151-
builder.AppendLine($"\t\tpublic {returnTypeString} {method.Name}( {parametersString} )");
142+
builder.AppendLine($"\t\t[global::WebApiClientCore.HttpApiProxyMethod({index}, {methodName})]");
143+
builder.AppendLine($"\t\t{returnTypeString} {GetFullName(interfaceType)}.{method.Name}( {parametersString} )");
152144
builder.AppendLine("\t\t{");
153145
builder.AppendLine($"\t\t\treturn ({returnTypeString})this.{this.apiInterceptorFieldName}.Intercept(this.{this.actionInvokersFieldName}[{index}], {paremterArrayString});");
154146
builder.AppendLine("\t\t}");

WebApiClientCore.Test/HttpApiTest.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
using Xunit;
34

45
namespace WebApiClientCore.Test
@@ -39,11 +40,11 @@ public void GetAllApiMethodsTest()
3940
var m2 = HttpApi.FindApiMethods(typeof(IMyApi));
4041

4142
Assert.False(object.ReferenceEquals(m1, m2));
42-
Assert.True(m1.Length == 3);
43+
Assert.Equal(3, m1.Length);
4344

4445
var m3 = HttpApi.FindApiMethods(typeof(IPostNew));
45-
Assert.Single(m3);
46-
Assert.True(m3[0].IsDefined(typeof(NewAttribute), true));
46+
Assert.Equal(2, m3.Length);
47+
Assert.Contains(m3, i => i.IsDefined(typeof(NewAttribute), true));
4748
}
4849
}
4950
}

WebApiClientCore/Exceptions/ProxyTypeCreateException.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,14 @@ namespace WebApiClientCore.Exceptions
55
/// <summary>
66
/// 表示代理类创建异常
77
/// </summary>
8-
public class ProxyTypeCreateException : Exception
8+
public class ProxyTypeCreateException : ProxyTypeException
99
{
10-
/// <summary>
11-
/// 接口类型
12-
/// </summary>
13-
public Type InterfaceType { get; }
14-
1510
/// <summary>
1611
/// 代理类创建异常
1712
/// </summary>
1813
/// <param name="interfaceType">接口类型</param>
1914
public ProxyTypeCreateException(Type interfaceType)
20-
: this(interfaceType, null)
15+
: base(interfaceType)
2116
{
2217
}
2318

@@ -27,9 +22,8 @@ public ProxyTypeCreateException(Type interfaceType)
2722
/// <param name="interfaceType">接口类型</param>
2823
/// <param name="message">提示消息</param>
2924
public ProxyTypeCreateException(Type interfaceType, string? message)
30-
: base(message)
25+
: base(interfaceType, message)
3126
{
32-
this.InterfaceType = interfaceType;
3327
}
3428
}
3529
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
3+
namespace WebApiClientCore.Exceptions
4+
{
5+
/// <summary>
6+
/// 表示代理类异常
7+
/// </summary>
8+
public class ProxyTypeException : Exception
9+
{
10+
/// <summary>
11+
/// 接口类型
12+
/// </summary>
13+
public Type InterfaceType { get; }
14+
15+
/// <summary>
16+
/// 代理类异常
17+
/// </summary>
18+
/// <param name="interfaceType">接口类型</param>
19+
public ProxyTypeException(Type interfaceType)
20+
: this(interfaceType, null)
21+
{
22+
}
23+
24+
/// <summary>
25+
/// 代理类创建异常
26+
/// </summary>
27+
/// <param name="interfaceType">接口类型</param>
28+
/// <param name="message">提示消息</param>
29+
public ProxyTypeException(Type interfaceType, string? message)
30+
: base(message)
31+
{
32+
this.InterfaceType = interfaceType;
33+
}
34+
}
35+
}

WebApiClientCore/HttpApi.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ public static MethodInfo[] FindApiMethods(Type httpApiType)
9797
throw new ArgumentException(Resx.required_InterfaceType.Format(httpApiType.Name));
9898
}
9999

100-
return HttpApiMethodFinder
101-
.FindApiMethods(httpApiType)
100+
return httpApiType.GetInterfaces().Append(httpApiType)
101+
.SelectMany(item => item.GetMethods())
102102
.Select(item => item.EnsureApiMethod())
103103
.ToArray();
104104
}

WebApiClientCore/HttpApiMethodFinder.cs

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

WebApiClientCore/HttpApiProxyMethodAttribute.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,20 @@ public sealed class HttpApiProxyMethodAttribute : Attribute
1515
/// </summary>
1616
public int Index { get; }
1717

18+
/// <summary>
19+
/// 获取名称
20+
/// </summary>
21+
public string Name { get; }
22+
1823
/// <summary>
1924
/// 方法的索引特性
2025
/// </summary>
2126
/// <param name="index">索引值,确保连续且不重复</param>
22-
public HttpApiProxyMethodAttribute(int index)
27+
/// <param name="name">方法的名称</param>
28+
public HttpApiProxyMethodAttribute(int index, string name)
2329
{
2430
this.Index = index;
31+
this.Name = name;
2532
}
2633
}
2734
}

WebApiClientCore/Implementations/EmitHttpApiActivator.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class EmitHttpApiActivator<
1515
#if NET5_0_OR_GREATER
1616
[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
1717
#endif
18-
THttpApi> : IHttpApiActivator<THttpApi>
18+
THttpApi> : IHttpApiActivator<THttpApi>
1919
{
2020
private readonly ApiActionInvoker[] actionInvokers;
2121
private readonly Func<IHttpApiInterceptor, ApiActionInvoker[], THttpApi> activator;
@@ -33,7 +33,7 @@ public EmitHttpApiActivator(IApiActionDescriptorProvider apiActionDescriptorProv
3333

3434
this.actionInvokers = apiMethods
3535
.Select(item => apiActionDescriptorProvider.CreateActionDescriptor(item, typeof(THttpApi)))
36-
.Select(item => actionInvokerProvider.CreateActionInvoker(item))
36+
.Select(actionInvokerProvider.CreateActionInvoker)
3737
.ToArray();
3838

3939
var proxyType = BuildProxyType(typeof(THttpApi), apiMethods);
@@ -151,17 +151,19 @@ private static void BuildCtor(TypeBuilder builder, FieldBuilder fieldApiIntercep
151151
/// <param name="fieldActionInvokers">action执行器字段</param>
152152
private static void BuildMethods(TypeBuilder builder, MethodInfo[] actionMethods, FieldBuilder fieldApiInterceptor, FieldBuilder fieldActionInvokers)
153153
{
154-
const MethodAttributes implementAttribute = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.HideBySig;
154+
// private final hidebysig newslot virtual
155+
const MethodAttributes implementAttribute = MethodAttributes.Private | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual;
155156

156157
for (var i = 0; i < actionMethods.Length; i++)
157158
{
158159
var actionMethod = actionMethods[i];
159160
var actionParameters = actionMethod.GetParameters();
160161
var parameterTypes = actionParameters.Select(p => p.ParameterType).ToArray();
162+
var actionMethodName = $"{actionMethod.DeclaringType?.FullName}.{actionMethod.Name}";
161163

162-
var iL = builder
163-
.DefineMethod(actionMethod.Name, implementAttribute, CallingConventions.Standard, actionMethod.ReturnType, parameterTypes)
164-
.GetILGenerator();
164+
var methodBuilder = builder.DefineMethod(actionMethodName, implementAttribute, CallingConventions.Standard | CallingConventions.HasThis, actionMethod.ReturnType, parameterTypes);
165+
builder.DefineMethodOverride(methodBuilder, actionMethod);
166+
var iL = methodBuilder.GetILGenerator();
165167

166168
// this.apiInterceptor
167169
iL.Emit(OpCodes.Ldarg_0);

0 commit comments

Comments
 (0)