@@ -85,33 +85,45 @@ private ValueTask<TResponse> SendCore<TRequest, TResponse>(in TRequest request,
8585 where TRequest : notnull
8686 where TResponse : notnull
8787 {
88- // ULTRA-FAST PATH: Singleton/Transient + unnamed + pipeline-free
89- // Uses direct delegate invocation - NO virtual calls
88+ // ULTRA-FAST PATH: Singleton/Transient + unnamed + pipeline-free (LightHandlerEntry)
9089 if ( string . IsNullOrEmpty ( name ) && IsFastPath ( spaceRegistry . HandlerLifetime ) )
9190 {
92- // Hot path: Already initialized and is light handler
9391 if ( DirectInvokerCache < TRequest , TResponse > . Initialized )
9492 {
9593 if ( DirectInvokerCache < TRequest , TResponse > . IsLight )
9694 {
9795 // Single cancellation check - ThrowIfCancellationRequested handles both
9896 ct . ThrowIfCancellationRequested ( ) ;
99- var lctx = new LightHandlerContext < TRequest > ( request , rootProvider , this , ct ) ;
100- return DirectInvokerCache < TRequest , TResponse > . LightInvoker ( in lctx ) ;
97+ return DirectInvokerCache < TRequest , TResponse > . LightInvoker (
98+ new LightHandlerContext < TRequest > ( request , rootProvider , this , ct ) ) ;
10199 }
102- // Not light - fall through to standard path (has pipelines)
103- }
104- else
105- {
106- // Cold path: Initialize cache (NoInlining to keep hot path small)
107- return InitializeAndInvoke < TRequest , TResponse > ( in request , ct ) ;
100+ // Has pipelines - use entry path
101+ return SendViaEntry < TRequest , TResponse > ( in request , ct ) ;
108102 }
103+
104+ // Cold path: Initialize and invoke
105+ return InitializeAndInvoke < TRequest , TResponse > ( in request , ct ) ;
109106 }
110107
111- // Standard path (named handlers, pipeline handlers, scoped)
108+ // Named or scoped path
112109 return SendCoreStandard < TRequest , TResponse > ( in request , name , ct ) ;
113110 }
114111
112+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
113+ private ValueTask < TResponse > SendViaEntry < TRequest , TResponse > ( in TRequest request , CancellationToken ct )
114+ where TRequest : notnull
115+ where TResponse : notnull
116+ {
117+ ct . ThrowIfCancellationRequested ( ) ;
118+ var entry = EntryCache < TRequest , TResponse > . Entry ;
119+
120+ if ( entry . HasLightInvoker )
121+ return entry . InvokeLight ( rootProvider , this , request , ct ) ;
122+
123+ var ctx = HandlerContext < TRequest > . Create ( rootProvider , request , ct ) ;
124+ return entry . Invoke ( ctx ) . AwaitAndReturnHandlerInvoke ( ctx ) ;
125+ }
126+
115127 [ MethodImpl ( MethodImplOptions . NoInlining ) ]
116128 private ValueTask < TResponse > InitializeAndInvoke < TRequest , TResponse > ( in TRequest request , CancellationToken ct )
117129 where TRequest : notnull
@@ -130,19 +142,14 @@ private ValueTask<TResponse> InitializeAndInvoke<TRequest, TResponse>(in TReques
130142 DirectInvokerCache < TRequest , TResponse > . Initialized = true ;
131143
132144 ct . ThrowIfCancellationRequested ( ) ;
133- var lctx = new LightHandlerContext < TRequest > ( request , rootProvider , this , ct ) ;
134- return DirectInvokerCache < TRequest , TResponse > . LightInvoker ( in lctx ) ;
145+ return DirectInvokerCache < TRequest , TResponse > . LightInvoker (
146+ new LightHandlerContext < TRequest > ( request , rootProvider , this , ct ) ) ;
135147 }
136148
137149 DirectInvokerCache < TRequest , TResponse > . IsLight = false ;
138150 DirectInvokerCache < TRequest , TResponse > . Initialized = true ;
139151
140- // Has pipelines - invoke through entry
141- if ( entry . HasLightInvoker )
142- return entry . InvokeLight ( rootProvider , this , request , ct ) ;
143-
144- var ctx = HandlerContext < TRequest > . Create ( rootProvider , request , ct ) ;
145- return entry . Invoke ( ctx ) . AwaitAndReturnHandlerInvoke ( ctx ) ;
152+ return SendViaEntry < TRequest , TResponse > ( in request , ct ) ;
146153 }
147154
148155 DirectInvokerCache < TRequest , TResponse > . IsLight = false ;
@@ -285,10 +292,7 @@ public ValueTask<TResponse> Send<TResponse>(IRequest<TResponse> request, string
285292 if ( vto . IsCompletedSuccessfully )
286293 return new ValueTask < TResponse > ( ( TResponse ) vto . Result ! ) ;
287294
288- return AwaitFast1 ( vto ) ;
289-
290- static async ValueTask < TResponse > AwaitFast1 ( ValueTask < object > vt )
291- => ( TResponse ) await vt . ConfigureAwait ( false ) ;
295+ return AwaitCast < TResponse > ( vto ) ;
292296 }
293297
294298 // Fallback: object dispatch through registry (still no expression compile)
@@ -297,10 +301,7 @@ static async ValueTask<TResponse> AwaitFast1(ValueTask<object> vt)
297301 if ( vtoFallback . IsCompletedSuccessfully )
298302 return new ValueTask < TResponse > ( ( TResponse ) vtoFallback . Result ! ) ;
299303
300- return AwaitFast2 ( vtoFallback ) ;
301-
302- static async ValueTask < TResponse > AwaitFast2 ( ValueTask < object > vt )
303- => ( TResponse ) await vt . ConfigureAwait ( false ) ;
304+ return AwaitCast < TResponse > ( vtoFallback ) ;
304305 }
305306
306307 // Scoped path
@@ -312,14 +313,15 @@ static async ValueTask<TResponse> AwaitFast2(ValueTask<object> vt)
312313 }
313314
314315 var vts = spaceRegistry . DispatchHandler ( request , name , typeof ( TResponse ) , scope . ServiceProvider , ct ) ;
315-
316316 if ( vts . IsCompletedSuccessfully )
317317 {
318318 scope . Dispose ( ) ;
319319 return new ValueTask < TResponse > ( ( TResponse ) vts . Result ! ) ;
320320 }
321-
322321 return AwaitDispose ( vts . ContinueWithCast < TResponse > ( ) , scope ) ;
322+
323+ static async ValueTask < T > AwaitCast < T > ( ValueTask < object > vt )
324+ => ( T ) await vt . ConfigureAwait ( false ) ;
323325 }
324326
325327 #endregion
@@ -339,34 +341,28 @@ public ValueTask<TResponse> Send<TResponse>(object request, string name = null,
339341 var key = ( type , name ?? string . Empty ) ;
340342
341343 if ( GenericDispatcherCache < TResponse > . Map . TryGetValue ( key , out var f ) )
342- {
343344 return f ( this , request , ct ) ;
344- }
345345
346346 // Build and cache dispatcher to typed Send<TRuntime,TResponse> when possible,
347347 // otherwise fall back to registry object dispatch.
348348 var del = BuildTypedDispatcher < TResponse > ( type , name ) ;
349349 GenericDispatcherCache < TResponse > . Map [ key ] = del ;
350-
351350 return del ( this , request , ct ) ;
352351 }
353352
354353 var scope = scopeFactory . CreateScope ( ) ;
355-
356354 if ( ct . IsCancellationRequested )
357355 {
358356 scope . Dispose ( ) ;
359357 return ValueTask . FromCanceled < TResponse > ( ct ) ;
360358 }
361359
362360 var vt = spaceRegistry . DispatchHandler ( request , name , typeof ( TResponse ) , scope . ServiceProvider , ct ) ;
363-
364361 if ( vt . IsCompletedSuccessfully )
365362 {
366363 scope . Dispose ( ) ;
367364 return new ValueTask < TResponse > ( ( TResponse ) vt . Result ! ) ;
368365 }
369-
370366 return AwaitDispose ( vt . ContinueWithCast < TResponse > ( ) , scope ) ;
371367 }
372368
@@ -377,12 +373,10 @@ public ValueTask Send(object request, string name = null, CancellationToken ct =
377373 var vt = Send < Nothing > ( request , name , ct ) ;
378374 if ( vt . IsCompletedSuccessfully )
379375 return default ;
380- return Await ( vt ) ;
376+ return AwaitNothing ( vt ) ;
381377
382- static async ValueTask Await ( ValueTask < Nothing > inner )
383- {
384- await inner . ConfigureAwait ( false ) ;
385- }
378+ static async ValueTask AwaitNothing ( ValueTask < Nothing > inner )
379+ => await inner . ConfigureAwait ( false ) ;
386380 }
387381
388382 private static Func < Space , object , CancellationToken , ValueTask < TRes > > BuildTypedDispatcher < TRes > ( Type requestType , string name )
@@ -435,8 +429,7 @@ public ValueTask Publish<TRequest>(TRequest request, CancellationToken ct = defa
435429 if ( IsFastPath ( spaceRegistry . HandlerLifetime ) )
436430 {
437431 var ctxFast = NotificationContext < TRequest > . Create ( rootProvider , request , ct ) ;
438- var vt = spaceRegistry . FastDispatchNotification ( ctxFast ) . AwaitAndReturnNotificationInvoke ( ctxFast ) ;
439- return vt ;
432+ return spaceRegistry . FastDispatchNotification ( ctxFast ) . AwaitAndReturnNotificationInvoke ( ctxFast ) ;
440433 }
441434
442435 return SlowPublishScoped ( request , ct ) ;
@@ -465,8 +458,7 @@ public ValueTask Publish<TRequest>(TRequest request, NotificationDispatchType di
465458 if ( IsFastPath ( spaceRegistry . HandlerLifetime ) )
466459 {
467460 var ctxFast = NotificationContext < TRequest > . Create ( rootProvider , request , ct ) ;
468- var vt = spaceRegistry . FastDispatchNotification ( ctxFast , dispatchType ) . AwaitAndReturnNotificationInvoke ( ctxFast ) ;
469- return vt ;
461+ return spaceRegistry . FastDispatchNotification ( ctxFast , dispatchType ) . AwaitAndReturnNotificationInvoke ( ctxFast ) ;
470462 }
471463
472464 return SlowPublishScoped ( request , dispatchType , ct ) ;
0 commit comments