2
2
3
3
internal abstract class ServiceClient : IDisposable
4
4
{
5
- #region " NonGeneric-Generic adapter cache "
6
- private static readonly MethodInfo GenericDefinition = ( ( Func < ServiceClient , MethodInfo , object ? [ ] , Task < int > > ) Invoke < int > ) . Method . GetGenericMethodDefinition ( ) ;
7
- private static readonly ConcurrentDictionary < Type , InvokeDelegate > ReturnTypeToInvokeDelegate = new ( ) ;
8
- private static InvokeDelegate GetInvokeDelegate ( Type returnType ) => ReturnTypeToInvokeDelegate . GetOrAdd ( returnType , CreateInvokeDelegate ) ;
9
- private static InvokeDelegate CreateInvokeDelegate ( Type returnType )
10
- => GenericDefinition . MakeGenericDelegate < InvokeDelegate > (
11
- returnType . IsGenericType
12
- ? returnType . GetGenericArguments ( ) [ 0 ]
13
- : typeof ( object ) ) ;
14
-
15
- private static Task < TResult > Invoke < TResult > ( ServiceClient serviceClient , MethodInfo method , object ? [ ] args ) => serviceClient . Invoke < TResult > ( method , args ) ;
16
- #endregion
17
-
18
- protected abstract TimeSpan RequestTimeout { get ; }
19
- protected abstract BeforeCallHandler ? BeforeCall { get ; }
20
- protected abstract ILogger ? Log { get ; }
21
- protected abstract string DebugName { get ; }
22
- protected abstract ISerializer ? Serializer { get ; }
5
+ protected abstract IServiceClientConfig Config { get ; }
23
6
public abstract Stream ? Network { get ; }
24
-
25
7
public event EventHandler ? ConnectionClosed ;
26
8
27
9
private readonly Type _interfaceType ;
@@ -33,7 +15,6 @@ protected ServiceClient(Type interfaceType)
33
15
}
34
16
35
17
protected void RaiseConnectionClosed ( ) => ConnectionClosed ? . Invoke ( this , EventArgs . Empty ) ;
36
-
37
18
public virtual ValueTask CloseConnection ( ) => throw new NotSupportedException ( ) ;
38
19
public object ? Invoke ( MethodInfo method , object ? [ ] args ) => GetInvokeDelegate ( method . ReturnType ) ( this , method , args ) ;
39
20
@@ -64,7 +45,7 @@ async Task<TResult> Invoke()
64
45
{
65
46
CancellationToken cancellationToken = default ;
66
47
TimeSpan messageTimeout = default ;
67
- TimeSpan clientTimeout = RequestTimeout ;
48
+ TimeSpan clientTimeout = Config . RequestTimeout ;
68
49
Stream ? uploadStream = null ;
69
50
var methodName = method . Name ;
70
51
@@ -77,10 +58,10 @@ async Task<TResult> Invoke()
77
58
78
59
var ( connection , newConnection ) = await EnsureConnection ( ct ) ;
79
60
80
- if ( BeforeCall is not null )
61
+ if ( Config . BeforeCall is not null )
81
62
{
82
63
var callInfo = new CallInfo ( newConnection , method , args ) ;
83
- await BeforeCall ( callInfo , ct ) ;
64
+ await Config . BeforeCall ( callInfo , ct ) ;
84
65
}
85
66
86
67
var requestId = connection . NewRequestId ( ) ;
@@ -89,11 +70,11 @@ async Task<TResult> Invoke()
89
70
UploadStream = uploadStream
90
71
} ;
91
72
92
- Log ? . ServiceClientCalling ( methodName , requestId , DebugName ) ;
73
+ Config . Logger ? . ServiceClientCalling ( methodName , requestId , Config . DebugName ) ;
93
74
var response = await connection . RemoteCall ( request , ct ) ; // returns user errors instead of throwing them (could throw for system bugs)
94
- Log ? . ServiceClientCalled ( methodName , requestId , DebugName ) ;
75
+ Config . Logger ? . ServiceClientCalled ( methodName , requestId , Config . DebugName ) ;
95
76
96
- return response . Deserialize < TResult > ( Serializer ) ;
77
+ return response . Deserialize < TResult > ( Config . Serializer ) ;
97
78
}
98
79
catch ( Exception ex )
99
80
{
@@ -127,7 +108,7 @@ string[] SerializeArguments()
127
108
break ;
128
109
}
129
110
130
- result [ index ] = Serializer . OrDefault ( ) . Serialize ( args [ index ] ) ;
111
+ result [ index ] = Config . Serializer . OrDefault ( ) . Serialize ( args [ index ] ) ;
131
112
}
132
113
133
114
return result ;
@@ -142,9 +123,22 @@ public void Dispose()
142
123
}
143
124
private void Dispose ( bool disposing )
144
125
{
145
- Log ? . ServiceClientDispose ( DebugName ) ;
126
+ Config . Logger ? . ServiceClientDispose ( Config . DebugName ) ;
146
127
}
147
- public override string ToString ( ) => DebugName ;
128
+ public override string ToString ( ) => Config . DebugName ;
129
+
130
+ #region Generic adapter cache
131
+ private static readonly MethodInfo GenericDefinition = ( ( Func < ServiceClient , MethodInfo , object ? [ ] , Task < int > > ) Invoke < int > ) . Method . GetGenericMethodDefinition ( ) ;
132
+ private static readonly ConcurrentDictionary < Type , InvokeDelegate > ReturnTypeToInvokeDelegate = new ( ) ;
133
+ private static InvokeDelegate GetInvokeDelegate ( Type returnType ) => ReturnTypeToInvokeDelegate . GetOrAdd ( returnType , CreateInvokeDelegate ) ;
134
+ private static InvokeDelegate CreateInvokeDelegate ( Type returnType )
135
+ => GenericDefinition . MakeGenericDelegate < InvokeDelegate > (
136
+ returnType . IsGenericType
137
+ ? returnType . GetGenericArguments ( ) [ 0 ]
138
+ : typeof ( object ) ) ;
139
+
140
+ private static Task < TResult > Invoke < TResult > ( ServiceClient serviceClient , MethodInfo method , object ? [ ] args ) => serviceClient . Invoke < TResult > ( method , args ) ;
141
+ #endregion
148
142
}
149
143
150
144
internal sealed class ServiceClientProper : ServiceClient
@@ -208,10 +202,16 @@ public override async ValueTask CloseConnection()
208
202
return ( LatestConnection , newlyConnected : false ) ;
209
203
}
210
204
211
- LatestConnection = new Connection ( await Connect ( ct ) , Serializer , Log , DebugName ) ;
205
+ if ( Config . BeforeConnect is not null )
206
+ {
207
+ await Config . BeforeConnect ( ct ) ;
208
+ }
209
+
210
+ var network = await Connect ( ct ) ;
211
+ LatestConnection = new Connection ( network , Config . Serializer , Config . Logger , Config . DebugName ) ;
212
212
var router = new Router ( _client . Config . CreateCallbackRouterConfig ( ) , _client . Config . ServiceProvider ) ;
213
213
_latestServer = new Server ( router , _client . Config . RequestTimeout , LatestConnection ) ;
214
- LatestConnection . Listen ( ) . LogException ( Log , DebugName ) ;
214
+ LatestConnection . Listen ( ) . LogException ( Config . Logger , Config . DebugName ) ;
215
215
return ( LatestConnection , newlyConnected : true ) ;
216
216
}
217
217
}
@@ -228,11 +228,7 @@ private async Task<Network> Connect(CancellationToken ct)
228
228
return network ;
229
229
}
230
230
231
- protected override TimeSpan RequestTimeout => _client . Config . RequestTimeout ;
232
- protected override BeforeCallHandler ? BeforeCall => _client . Config . BeforeCall ;
233
- protected override ILogger ? Log => _client . Config . Logger ;
234
- protected override string DebugName => _client . Transport . ToString ( ) ;
235
- protected override ISerializer ? Serializer => _client . Config . Serializer ;
231
+ protected override IServiceClientConfig Config => _client . Config ;
236
232
}
237
233
238
234
internal sealed class ServiceClientForCallback : ServiceClient
@@ -251,9 +247,5 @@ public ServiceClientForCallback(Connection connection, Listener listener, Type i
251
247
protected override Task < ( Connection connection , bool newlyConnected ) > EnsureConnection ( CancellationToken ct )
252
248
=> Task . FromResult ( ( _connection , newlyConnected : false ) ) ;
253
249
254
- protected override TimeSpan RequestTimeout => _listener . Config . RequestTimeout ;
255
- protected override BeforeCallHandler ? BeforeCall => null ;
256
- protected override ILogger ? Log => null ;
257
- protected override string DebugName => $ "ReverseClient for { _listener } ";
258
- protected override ISerializer ? Serializer => null ;
250
+ protected override IServiceClientConfig Config => _listener . Config ;
259
251
}
0 commit comments