22
33internal abstract class ServiceClient : IDisposable
44{
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 ; }
236 public abstract Stream ? Network { get ; }
24-
257 public event EventHandler ? ConnectionClosed ;
268
279 private readonly Type _interfaceType ;
@@ -33,7 +15,6 @@ protected ServiceClient(Type interfaceType)
3315 }
3416
3517 protected void RaiseConnectionClosed ( ) => ConnectionClosed ? . Invoke ( this , EventArgs . Empty ) ;
36-
3718 public virtual ValueTask CloseConnection ( ) => throw new NotSupportedException ( ) ;
3819 public object ? Invoke ( MethodInfo method , object ? [ ] args ) => GetInvokeDelegate ( method . ReturnType ) ( this , method , args ) ;
3920
@@ -64,7 +45,7 @@ async Task<TResult> Invoke()
6445 {
6546 CancellationToken cancellationToken = default ;
6647 TimeSpan messageTimeout = default ;
67- TimeSpan clientTimeout = RequestTimeout ;
48+ TimeSpan clientTimeout = Config . RequestTimeout ;
6849 Stream ? uploadStream = null ;
6950 var methodName = method . Name ;
7051
@@ -77,10 +58,10 @@ async Task<TResult> Invoke()
7758
7859 var ( connection , newConnection ) = await EnsureConnection ( ct ) ;
7960
80- if ( BeforeCall is not null )
61+ if ( Config . BeforeCall is not null )
8162 {
8263 var callInfo = new CallInfo ( newConnection , method , args ) ;
83- await BeforeCall ( callInfo , ct ) ;
64+ await Config . BeforeCall ( callInfo , ct ) ;
8465 }
8566
8667 var requestId = connection . NewRequestId ( ) ;
@@ -89,11 +70,11 @@ async Task<TResult> Invoke()
8970 UploadStream = uploadStream
9071 } ;
9172
92- Log ? . ServiceClientCalling ( methodName , requestId , DebugName ) ;
73+ Config . Logger ? . ServiceClientCalling ( methodName , requestId , Config . DebugName ) ;
9374 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 ) ;
9576
96- return response . Deserialize < TResult > ( Serializer ) ;
77+ return response . Deserialize < TResult > ( Config . Serializer ) ;
9778 }
9879 catch ( Exception ex )
9980 {
@@ -127,7 +108,7 @@ string[] SerializeArguments()
127108 break ;
128109 }
129110
130- result [ index ] = Serializer . OrDefault ( ) . Serialize ( args [ index ] ) ;
111+ result [ index ] = Config . Serializer . OrDefault ( ) . Serialize ( args [ index ] ) ;
131112 }
132113
133114 return result ;
@@ -142,9 +123,22 @@ public void Dispose()
142123 }
143124 private void Dispose ( bool disposing )
144125 {
145- Log ? . ServiceClientDispose ( DebugName ) ;
126+ Config . Logger ? . ServiceClientDispose ( Config . DebugName ) ;
146127 }
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
148142}
149143
150144internal sealed class ServiceClientProper : ServiceClient
@@ -208,10 +202,16 @@ public override async ValueTask CloseConnection()
208202 return ( LatestConnection , newlyConnected : false ) ;
209203 }
210204
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 ) ;
212212 var router = new Router ( _client . Config . CreateCallbackRouterConfig ( ) , _client . Config . ServiceProvider ) ;
213213 _latestServer = new Server ( router , _client . Config . RequestTimeout , LatestConnection ) ;
214- LatestConnection . Listen ( ) . LogException ( Log , DebugName ) ;
214+ LatestConnection . Listen ( ) . LogException ( Config . Logger , Config . DebugName ) ;
215215 return ( LatestConnection , newlyConnected : true ) ;
216216 }
217217 }
@@ -228,11 +228,7 @@ private async Task<Network> Connect(CancellationToken ct)
228228 return network ;
229229 }
230230
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 ;
236232}
237233
238234internal sealed class ServiceClientForCallback : ServiceClient
@@ -251,9 +247,5 @@ public ServiceClientForCallback(Connection connection, Listener listener, Type i
251247 protected override Task < ( Connection connection , bool newlyConnected ) > EnsureConnection ( CancellationToken ct )
252248 => Task . FromResult ( ( _connection , newlyConnected : false ) ) ;
253249
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 ;
259251}
0 commit comments