@@ -11,37 +11,39 @@ namespace WebApiClient
1111 /// 提供HttpApi的配置注册和实例创建
1212 /// 并对实例的生命周期进行自动管理
1313 /// </summary>
14- public partial class HttpApiFactory : IHttpApiFactory , _IHttpApiFactory
14+ public class HttpApiFactory < TInterface > : IHttpApiFactory < TInterface > , IHttpApiFactory , _IHttpApiFactory
15+ where TInterface : class , IHttpApi
1516 {
1617 /// <summary>
17- /// handler的生命周期
18+ /// HttpApiConfig的配置委托
1819 /// </summary>
19- private TimeSpan lifeTime = TimeSpan . FromMinutes ( 2d ) ;
20+ private readonly Action < HttpApiConfig > configAction ;
2021
2122 /// <summary>
22- /// 清理handler时间间隔
23+ /// HttpMessageHandler的创建委托
2324 /// </summary>
24- private TimeSpan cleanupInterval = TimeSpan . FromSeconds ( 10d ) ;
25+ private readonly Func < HttpMessageHandler > handlerFunc ;
2526
2627 /// <summary>
27- /// 过期的记录
28+ /// handler的生命周期
2829 /// </summary>
29- private readonly ConcurrentQueue < ExpiredEntry > expiredEntries ;
30+ private TimeSpan lifeTime = TimeSpan . FromMinutes ( 2d ) ;
3031
3132 /// <summary>
32- /// 激活记录的创建工厂
33+ /// 清理handler时间间隔
3334 /// </summary>
34- private readonly Func < Type , Lazy < ActiveEntry > > activeEntryFactory ;
35+ private TimeSpan cleanupInterval = TimeSpan . FromSeconds ( 10d ) ;
3536
3637 /// <summary>
37- /// http接口代理创建选项
38+ /// 激活的记录
3839 /// </summary>
39- private readonly ConcurrentDictionary < Type , HttpApiCreateOption > httpApiCreateOptions ;
40+ private volatile Lazy < ActiveEntry > activeEntryLazy ;
4041
4142 /// <summary>
42- /// 激活的记录
43+ /// 过期的记录
4344 /// </summary>
44- private readonly ConcurrentDictionary < Type , Lazy < ActiveEntry > > activeEntries ;
45+ private readonly ConcurrentQueue < ExpiredEntry > expiredEntries ;
46+
4547
4648 /// <summary>
4749 /// 获取已过期但还未释放的HttpApi实例数量
@@ -95,78 +97,72 @@ public TimeSpan CleanupInterval
9597 /// HttpApi创建工厂
9698 /// </summary>
9799 public HttpApiFactory ( )
100+ : this ( configAction : null )
98101 {
102+ }
103+
104+ /// <summary>
105+ /// HttpApi创建工厂
106+ /// </summary>
107+ /// <param name="configAction">HttpApiConfig的配置委托</param>
108+ public HttpApiFactory ( Action < HttpApiConfig > configAction )
109+ : this ( configAction , handlerFunc : null )
110+ {
111+ }
112+
113+ /// <summary>
114+ /// HttpApi创建工厂
115+ /// </summary>
116+ /// <param name="configAction">HttpApiConfig的配置委托</param>
117+ /// <param name="handlerFunc">HttpMessageHandler的创建委托</param>
118+ public HttpApiFactory ( Action < HttpApiConfig > configAction , Func < HttpMessageHandler > handlerFunc )
119+ {
120+ this . configAction = configAction ;
121+ this . handlerFunc = handlerFunc ?? new Func < HttpMessageHandler > ( ( ) => new DefaultHttpClientHandler ( ) ) ;
122+
99123 this . expiredEntries = new ConcurrentQueue < ExpiredEntry > ( ) ;
100- this . activeEntries = new ConcurrentDictionary < Type , Lazy < ActiveEntry > > ( ) ;
101- this . httpApiCreateOptions = new ConcurrentDictionary < Type , HttpApiCreateOption > ( ) ;
102- this . activeEntryFactory = apiType => new Lazy < ActiveEntry > ( ( ) => this . CreateActiveEntry ( apiType ) , LazyThreadSafetyMode . ExecutionAndPublication ) ;
124+ this . activeEntryLazy = new Lazy < ActiveEntry > ( this . CreateActiveEntry , LazyThreadSafetyMode . ExecutionAndPublication ) ;
103125
104126 this . RegisteCleanup ( ) ;
105127 }
106128
107129 /// <summary>
108- /// 注册http接口
130+ /// 创建接口的代理实例
109131 /// </summary>
110- /// <typeparam name="TInterface"></typeparam>
111- /// <param name="config">HttpApiConfig的配置</param>
112- /// <param name="handlerFactory">HttpMessageHandler创建委托</param>
113132 /// <returns></returns>
114- public bool AddHttpApi < TInterface > ( Action < HttpApiConfig > config , Func < HttpMessageHandler > handlerFactory ) where TInterface : class , IHttpApi
133+ public TInterface CreateHttpApi ( )
115134 {
116- if ( handlerFactory == null )
117- {
118- handlerFactory = ( ) => new DefaultHttpClientHandler ( ) ;
119- }
120-
121- var options = new HttpApiCreateOption
122- {
123- ConfigAction = config ,
124- HandlerFactory = handlerFactory
125- } ;
126-
127- return this . httpApiCreateOptions . TryAdd ( typeof ( TInterface ) , options ) ;
135+ return ( ( IHttpApiFactory ) this ) . CreateHttpApi ( ) as TInterface ;
128136 }
129137
130138 /// <summary>
131- /// 创建指定接口的代理实例
139+ /// 创建接口的代理实例
132140 /// </summary>
133- /// <typeparam name="TInterface"></typeparam>
134- /// <exception cref="ArgumentException"></exception>
135141 /// <returns></returns>
136- public TInterface CreateHttpApi < TInterface > ( ) where TInterface : class , IHttpApi
142+ object IHttpApiFactory . CreateHttpApi ( )
137143 {
138- var apiType = typeof ( TInterface ) ;
139- var entry = this . activeEntries . GetOrAdd ( apiType , this . activeEntryFactory ) . Value ;
140- return HttpApiClient . Create ( apiType , entry . Interceptor ) as TInterface ;
144+ var interceptor = this . activeEntryLazy . Value . Interceptor ;
145+ return HttpApiClient . Create ( typeof ( TInterface ) , interceptor ) ;
141146 }
142147
143148 /// <summary>
144149 /// 创建激活状态的记录
145150 /// </summary>
146- /// <param name="apiType">http接口类型</param>
147- /// <exception cref="ArgumentException"></exception>
148151 /// <returns></returns>
149- private ActiveEntry CreateActiveEntry ( Type apiType )
152+ private ActiveEntry CreateActiveEntry ( )
150153 {
151- if ( this . httpApiCreateOptions . TryGetValue ( apiType , out var option ) == false )
152- {
153- throw new ArgumentException ( $ "未注册的接口类型{ apiType } ") ;
154- }
155-
156- var handler = option . HandlerFactory . Invoke ( ) ;
157- var httpApiConfig = new HttpApiConfig ( handler , false ) ;
154+ var httpApiConfig = new HttpApiConfig ( this . handlerFunc . Invoke ( ) , true ) ;
158155 var interceptor = new LifeTimeTrackingInterceptor ( httpApiConfig ) ;
159156
160- if ( option . ConfigAction != null )
157+ if ( this . configAction != null )
161158 {
162- option . ConfigAction . Invoke ( httpApiConfig ) ;
159+ this . configAction . Invoke ( httpApiConfig ) ;
163160 }
164161
165162 return new ActiveEntry ( this )
166163 {
167- ApiType = apiType ,
168- Disposable = httpApiConfig ,
169- Interceptor = interceptor
164+ Interceptor = interceptor ,
165+ Disposable = httpApiConfig
170166 } ;
171167 }
172168
@@ -176,7 +172,9 @@ private ActiveEntry CreateActiveEntry(Type apiType)
176172 /// <param name="active">激活的记录</param>
177173 void _IHttpApiFactory . OnEntryDeactivate ( ActiveEntry active )
178174 {
179- this . activeEntries . TryRemove ( active . ApiType , out var _ ) ;
175+ // 切换激活状态的记录的实例
176+ this . activeEntryLazy = new Lazy < ActiveEntry > ( this . CreateActiveEntry , LazyThreadSafetyMode . ExecutionAndPublication ) ;
177+
180178 var expired = new ExpiredEntry ( active ) ;
181179 this . expiredEntries . Enqueue ( expired ) ;
182180 }
@@ -214,5 +212,6 @@ private void CleanupCallback()
214212
215213 this . RegisteCleanup ( ) ;
216214 }
215+
217216 }
218217}
0 commit comments