@@ -31,19 +31,22 @@ public class CoreBenchmarks
3131 private readonly FoundatioCommandHandler _directCommandHandler = new ( ) ;
3232 private readonly FoundatioQueryHandler _directQueryHandler = new ( ) ;
3333 private readonly FoundatioEventHandler _directEventHandler = new ( ) ;
34- private FoundatioQueryWithDependenciesHandler _directQueryWithDependenciesHandler = null ! ;
34+ private readonly FoundatioCreateOrderHandler _directCreateOrderHandler = new ( ) ;
35+ private readonly FoundatioOrderCreatedHandler1 _directOrderCreatedHandler1 = new ( ) ;
36+ private readonly FoundatioOrderCreatedHandler2 _directOrderCreatedHandler2 = new ( ) ;
37+ private FoundatioFullQueryHandler _directFullQueryHandler = null ! ;
3538
3639 private readonly PingCommand _pingCommand = new ( "test-123" ) ;
3740 private readonly GetOrder _getOrder = new ( 42 ) ;
38- private readonly GetOrderWithDependencies _getOrderWithDependencies = new ( 42 ) ;
41+ private readonly GetFullQuery _getFullQuery = new ( 42 ) ;
3942 private readonly GetCachedOrder _getCachedOrder = new ( 42 ) ;
4043 private readonly UserRegisteredEvent _userRegisteredEvent = new ( "User-456" , "test@example.com" ) ;
4144 private readonly CreateOrder _createOrder = new ( 123 , 99.99m ) ;
4245
4346 // MediatorNet-specific message types (uses different interfaces)
4447 private readonly MediatorNetPingCommand _mediatorNetPingCommand = new ( "test-123" ) ;
4548 private readonly MediatorNetGetOrder _mediatorNetGetOrder = new ( 42 ) ;
46- private readonly MediatorNetGetOrderWithDependencies _mediatorNetGetOrderWithDependencies = new ( 42 ) ;
49+ private readonly MediatorNetGetFullQuery _mediatorNetGetFullQuery = new ( 42 ) ;
4750 private readonly MediatorNetUserRegisteredEvent _mediatorNetUserRegisteredEvent = new ( "User-456" , "test@example.com" ) ;
4851 private readonly MediatorNetCreateOrder _mediatorNetCreateOrder = new ( 123 , 99.99m ) ;
4952 private readonly MediatorNetGetCachedOrder _mediatorNetGetCachedOrder = new ( 42 ) ;
@@ -58,8 +61,8 @@ public void Setup()
5861 _foundatioServices = foundatioServices . BuildServiceProvider ( ) ;
5962 _foundatioMediator = _foundatioServices . GetRequiredService < Foundatio . Mediator . IMediator > ( ) ;
6063
61- // Create direct handler with DI
62- _directQueryWithDependenciesHandler = new FoundatioQueryWithDependenciesHandler (
64+ // Create direct handler with DI for FullQuery baseline
65+ _directFullQueryHandler = new FoundatioFullQueryHandler (
6366 _foundatioServices . GetRequiredService < IOrderService > ( ) ) ;
6467
6568 // Setup MediatR
@@ -68,8 +71,8 @@ public void Setup()
6871 mediatrServices . AddMediatR ( cfg =>
6972 {
7073 cfg . RegisterServicesFromAssemblyContaining < CoreBenchmarks > ( ) ;
71- // Register timing behavior for GetOrderWithDependencies to match Foundatio's middleware
72- cfg . AddBehavior < MediatR . IPipelineBehavior < GetOrderWithDependencies , Order > , Handlers . MediatR . TimingBehavior < GetOrderWithDependencies , Order > > ( ) ;
74+ // Register timing behavior for GetFullQuery to match Foundatio's middleware
75+ cfg . AddBehavior < MediatR . IPipelineBehavior < GetFullQuery , Order > , Handlers . MediatR . TimingBehavior < GetFullQuery , Order > > ( ) ;
7376 // Register short-circuit behavior for GetCachedOrder
7477 cfg . AddBehavior < MediatR . IPipelineBehavior < GetCachedOrder , Order > , Handlers . MediatR . ShortCircuitBehavior > ( ) ;
7578 // Use parallel notification publisher to match Foundatio/MassTransit behavior
@@ -87,7 +90,7 @@ public void Setup()
8790 cfg . AddConsumer < Handlers . MassTransit . MassTransitQueryConsumer > ( ) ;
8891 cfg . AddConsumer < Handlers . MassTransit . MassTransitEventConsumer > ( ) ;
8992 cfg . AddConsumer < Handlers . MassTransit . MassTransitEventConsumer2 > ( ) ;
90- cfg . AddConsumer < Handlers . MassTransit . MassTransitQueryWithDependenciesConsumer > ( ) ;
93+ cfg . AddConsumer < Handlers . MassTransit . MassTransitFullQueryConsumer > ( ) ;
9194 cfg . AddConsumer < Handlers . MassTransit . MassTransitCreateOrderConsumer > ( ) ;
9295 cfg . AddConsumer < Handlers . MassTransit . MassTransitOrderCreatedConsumer1 > ( ) ;
9396 cfg . AddConsumer < Handlers . MassTransit . MassTransitOrderCreatedConsumer2 > ( ) ;
@@ -122,7 +125,7 @@ public void Setup()
122125 . IncludeType < Handlers . Wolverine . WolverineQueryHandler > ( )
123126 . IncludeType < Handlers . Wolverine . WolverineEventHandler > ( )
124127 . IncludeType < Handlers . Wolverine . WolverineEventHandler2 > ( )
125- . IncludeType < Handlers . Wolverine . WolverineQueryWithDependenciesHandler > ( )
128+ . IncludeType < Handlers . Wolverine . WolverineFullQueryHandler > ( )
126129 . IncludeType < Handlers . Wolverine . WolverineCreateOrderHandler > ( )
127130 . IncludeType < Handlers . Wolverine . WolverineOrderCreatedHandler1 > ( )
128131 . IncludeType < Handlers . Wolverine . WolverineOrderCreatedHandler2 > ( )
@@ -166,16 +169,11 @@ public async Task<Order> Direct_Query()
166169 }
167170
168171 [ Benchmark ]
169- public async Task Direct_Event ( )
172+ public async Task Direct_Publish ( )
170173 {
171174 await _directEventHandler . HandleAsync ( _userRegisteredEvent ) ;
172175 }
173176
174- [ Benchmark ]
175- public async Task < Order > Direct_QueryWithDependencies ( )
176- {
177- return await _directQueryWithDependenciesHandler . HandleAsync ( _getOrderWithDependencies ) ;
178- }
179177
180178 // Scenario 1: InvokeAsync without response (Command)
181179 [ Benchmark ]
@@ -272,40 +270,65 @@ public async Task MediatorNet_Publish()
272270 await _mediatorNetMediator . Publish ( _mediatorNetUserRegisteredEvent ) ;
273271 }
274272
275- // Scenario 4: InvokeAsync<T> with DI (Query with dependency injection)
273+ // Scenario 4: InvokeAsync<T> with DI (Query with dependency injection and middleware)
274+ [ Benchmark ]
275+ public async Task < Order > Direct_FullQuery ( )
276+ {
277+ // Simulate TimingMiddleware.Before
278+ var stopwatch = System . Diagnostics . Stopwatch . StartNew ( ) ;
279+ try
280+ {
281+ return await _directFullQueryHandler . HandleAsync ( _getFullQuery ) ;
282+ }
283+ finally
284+ {
285+ // Simulate TimingMiddleware.Finally
286+ stopwatch . Stop ( ) ;
287+ }
288+ }
289+
276290 [ Benchmark ]
277291 public async Task < Order > Foundatio_FullQuery ( )
278292 {
279- return await _foundatioMediator . InvokeAsync < Order > ( _getOrderWithDependencies ) ;
293+ return await _foundatioMediator . InvokeAsync < Order > ( _getFullQuery ) ;
280294 }
281295
282296 [ Benchmark ]
283297 public async Task < Order > MediatR_FullQuery ( )
284298 {
285- return await _mediatrMediator . Send ( _getOrderWithDependencies ) ;
299+ return await _mediatrMediator . Send ( _getFullQuery ) ;
286300 }
287301
288302 [ Benchmark ]
289303 public async Task < Order > MassTransit_FullQuery ( )
290304 {
291- var client = _masstransitMediator . CreateRequestClient < GetOrderWithDependencies > ( ) ;
292- var response = await client . GetResponse < Order > ( _getOrderWithDependencies ) ;
305+ var client = _masstransitMediator . CreateRequestClient < GetFullQuery > ( ) ;
306+ var response = await client . GetResponse < Order > ( _getFullQuery ) ;
293307 return response . Message ;
294308 }
295309
296310 [ Benchmark ]
297311 public async Task < Order ? > Wolverine_FullQuery ( )
298312 {
299- return await _wolverineBus . InvokeAsync < Order > ( _getOrderWithDependencies ) ;
313+ return await _wolverineBus . InvokeAsync < Order > ( _getFullQuery ) ;
300314 }
301315
302316 [ Benchmark ]
303317 public async Task < Order > MediatorNet_FullQuery ( )
304318 {
305- return await _mediatorNetMediator . Send ( _mediatorNetGetOrderWithDependencies ) ;
319+ return await _mediatorNetMediator . Send ( _mediatorNetGetFullQuery ) ;
306320 }
307321
308322 // Scenario 5: Cascading messages - invoke returns result and auto-publishes events to multiple handlers
323+ [ Benchmark ]
324+ public async Task < Order > Direct_CascadingMessages ( )
325+ {
326+ var ( order , evt ) = await _directCreateOrderHandler . HandleAsync ( _createOrder ) ;
327+ await _directOrderCreatedHandler1 . HandleAsync ( evt ) ;
328+ await _directOrderCreatedHandler2 . HandleAsync ( evt ) ;
329+ return order ;
330+ }
331+
309332 [ Benchmark ]
310333 public async Task < Order > Foundatio_CascadingMessages ( )
311334 {
@@ -340,6 +363,15 @@ public async Task<Order> MediatorNet_CascadingMessages()
340363
341364 // Scenario 6: Short-circuit middleware - returns cached result, handler is never invoked
342365 // Tests the cost of short-circuiting via middleware (caching, validation, auth, etc.)
366+ private static readonly Order _cachedOrder = new ( 999 , 49.99m , DateTime . UtcNow ) ;
367+
368+ [ Benchmark ]
369+ public Task < Order > Direct_ShortCircuit ( )
370+ {
371+ // Simulate ShortCircuitMiddleware.Before returning cached result
372+ return Task . FromResult ( _cachedOrder ) ;
373+ }
374+
343375 [ Benchmark ]
344376 public async Task < Order > Foundatio_ShortCircuit ( )
345377 {
0 commit comments