Skip to content

Commit f56deac

Browse files
committed
优化ProxyClassType的查找
1 parent 85b8068 commit f56deac

File tree

3 files changed

+80
-43
lines changed

3 files changed

+80
-43
lines changed

WebApiClientCore/Implementations/EmitHttpApiActivator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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);

WebApiClientCore/Implementations/SourceGeneratorHttpApiActivator.cs

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ public class SourceGeneratorHttpApiActivator<
1919
{
2020
private readonly ApiActionInvoker[] actionInvokers;
2121
private readonly Func<IHttpApiInterceptor, ApiActionInvoker[], THttpApi> activator;
22-
private static readonly Type? proxyClassType = FindProxyTypeFromAssembly();
22+
private static readonly Type? _proxyClassType = SourceGeneratorProxyClassType.Find(typeof(THttpApi));
2323

2424
/// <summary>
2525
/// 获取是否支持
2626
/// </summary>
27-
public static bool IsSupported => proxyClassType != null;
27+
public static bool IsSupported => _proxyClassType != null;
2828

2929
/// <summary>
3030
/// 通过查找类型代理类型创建实例
@@ -36,19 +36,20 @@ public class SourceGeneratorHttpApiActivator<
3636
/// <exception cref="ProxyTypeCreateException"></exception>
3737
public SourceGeneratorHttpApiActivator(IApiActionDescriptorProvider apiActionDescriptorProvider, IApiActionInvokerProvider actionInvokerProvider)
3838
{
39-
var proxyType = proxyClassType;
40-
if (proxyType == null)
39+
var httpApiType = typeof(THttpApi);
40+
var proxyClassType = _proxyClassType;
41+
if (proxyClassType == null)
4142
{
42-
var message = $"找不到{typeof(THttpApi)}的代理类";
43-
throw new ProxyTypeCreateException(typeof(THttpApi), message);
43+
var message = $"找不到{httpApiType}的代理类";
44+
throw new ProxyTypeCreateException(httpApiType, message);
4445
}
4546

46-
this.actionInvokers = FindApiMethods(proxyType)
47-
.Select(item => apiActionDescriptorProvider.CreateActionDescriptor(item, typeof(THttpApi)))
47+
this.actionInvokers = FindApiMethods(httpApiType, proxyClassType)
48+
.Select(item => apiActionDescriptorProvider.CreateActionDescriptor(item, httpApiType))
4849
.Select(actionInvokerProvider.CreateActionInvoker)
4950
.ToArray();
5051

51-
this.activator = LambdaUtil.CreateCtorFunc<IHttpApiInterceptor, ApiActionInvoker[], THttpApi>(proxyType);
52+
this.activator = LambdaUtil.CreateCtorFunc<IHttpApiInterceptor, ApiActionInvoker[], THttpApi>(proxyClassType);
5253
}
5354

5455
/// <summary>
@@ -62,49 +63,25 @@ public THttpApi CreateInstance(IHttpApiInterceptor apiInterceptor)
6263
}
6364

6465
/// <summary>
65-
/// 查找接口的Api方法
66+
/// 查找接口的方法
6667
/// </summary>
68+
/// <param name="httpApiType">接口类型</param>
69+
/// <param name="proxyClassType">接口的实现类型</param>
6770
/// <returns></returns>
68-
private static MethodInfo[] FindApiMethods(Type proxyType)
71+
private static MethodInfo[] FindApiMethods(Type httpApiType, Type proxyClassType)
6972
{
70-
var apiMethods = HttpApi.FindApiMethods(typeof(THttpApi));
71-
var proxyMethods = proxyType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
73+
var apiMethods = HttpApi.FindApiMethods(httpApiType);
74+
var classMethods = proxyClassType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
7275

7376
var methods = from a in apiMethods.Select(item => new MethodFeature(item))
74-
join p in proxyMethods.Select(item => new MethodFeature(item))
75-
on a equals p
76-
orderby p.Index
77+
join c in classMethods.Select(item => new MethodFeature(item))
78+
on a equals c
79+
orderby c.Index
7780
select a.Method;
7881

7982
return methods.ToArray();
8083
}
8184

82-
/// <summary>
83-
/// 从接口所在程序集查找代理类
84-
/// </summary>
85-
/// <returns></returns>
86-
private static Type? FindProxyTypeFromAssembly()
87-
{
88-
var interfaceType = typeof(THttpApi);
89-
foreach (var proxyType in interfaceType.Assembly.GetTypes())
90-
{
91-
if (proxyType.IsClass == false)
92-
{
93-
continue;
94-
}
95-
96-
var proxyClassAttr = proxyType.GetCustomAttribute<HttpApiProxyClassAttribute>();
97-
if (proxyClassAttr == null || proxyClassAttr.HttpApiType != interfaceType)
98-
{
99-
continue;
100-
}
101-
102-
return proxyType;
103-
}
104-
105-
return null;
106-
}
107-
10885
/// <summary>
10986
/// 表示MethodInfo的特征
11087
/// </summary>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
4+
using System.Reflection;
5+
6+
namespace WebApiClientCore.Implementations
7+
{
8+
/// <summary>
9+
/// 提供获取SourceGenerator生成的代理类型
10+
/// </summary>
11+
static class SourceGeneratorProxyClassType
12+
{
13+
private static readonly object syncRoot = new();
14+
private static readonly HashSet<Assembly> assemblies = [];
15+
private static readonly ConcurrentDictionary<Type, Type> httpApiProxyClassTable = [];
16+
17+
/// <summary>
18+
/// 查找指定接口类型的代理类类型
19+
/// </summary>
20+
/// <param name="httpApiType">接口类型</param>
21+
/// <returns></returns>
22+
public static Type? Find(Type httpApiType)
23+
{
24+
AnalyzeAssembly(httpApiType.Assembly);
25+
26+
if (httpApiProxyClassTable.TryGetValue(httpApiType, out var proxyClassType))
27+
{
28+
return proxyClassType;
29+
}
30+
return null;
31+
}
32+
33+
34+
private static void AnalyzeAssembly(Assembly assembly)
35+
{
36+
if (AddAssembly(assembly))
37+
{
38+
foreach (var classType in assembly.GetTypes())
39+
{
40+
if (classType.IsClass)
41+
{
42+
var proxyClassAttr = classType.GetCustomAttribute<HttpApiProxyClassAttribute>();
43+
if (proxyClassAttr != null)
44+
{
45+
httpApiProxyClassTable.TryAdd(proxyClassAttr.HttpApiType, classType);
46+
}
47+
}
48+
}
49+
}
50+
}
51+
52+
private static bool AddAssembly(Assembly assembly)
53+
{
54+
lock (syncRoot)
55+
{
56+
return assemblies.Add(assembly);
57+
}
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)