Skip to content

Commit a8238e6

Browse files
committed
Various updates
1 parent 60224bf commit a8238e6

26 files changed

Lines changed: 1830 additions & 167 deletions

benchmarks/Foundatio.Mediator.Benchmarks/Foundatio.Mediator.Benchmarks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<ItemGroup>
4343
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
4444
<PackageReference Include="MassTransit" Version="8.5.7" />
45-
<PackageReference Include="MediatR" Version="14.0.0" />
45+
<PackageReference Include="MediatR" Version="12.5.0" />
4646
<PackageReference Include="WolverineFx" Version="5.9.2" />
4747
<PackageReference Include="Mediator.Abstractions" Version="3.0.1" />
4848
<PackageReference Include="Mediator.SourceGenerator" Version="3.0.1">

docs/guide/performance.md

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Foundatio.Mediator aims to get as close to direct method call performance as pos
44

55
## Benchmark Results
66

7-
> 📊 **Last Updated:** 2025-12-23
7+
> 📊 **Last Updated:** 2026-01-06
88
99
### Commands
1010

@@ -14,12 +14,12 @@ Fire-and-forget dispatch with no return value.
1414
<thead>
1515
<tr><th style="text-align:left">Method</th><th style="text-align:right;white-space:nowrap">Mean</th><th style="text-align:right;white-space:nowrap">Allocated</th></tr>
1616
</thead>
17-
<tbody><tr><td style="width:100%"><code>Direct_Command</code></td><td style="text-align:right;white-space:nowrap">3.036 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
18-
<tr><td style="width:100%"><code>Foundatio_Command</code></td><td style="text-align:right;white-space:nowrap">5.127 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
19-
<tr><td style="width:100%"><code>MediatorNet_Command</code></td><td style="text-align:right;white-space:nowrap">11.742 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
20-
<tr><td style="width:100%"><code>MediatR_Command</code></td><td style="text-align:right;white-space:nowrap">54.904 ns</td><td style="text-align:right;white-space:nowrap">128 B</td></tr>
21-
<tr><td style="width:100%"><code>Wolverine_Command</code></td><td style="text-align:right;white-space:nowrap">240.127 ns</td><td style="text-align:right;white-space:nowrap">704 B</td></tr>
22-
<tr><td style="width:100%"><code>MassTransit_Command</code></td><td style="text-align:right;white-space:nowrap">1,736.321 ns</td><td style="text-align:right;white-space:nowrap">4,192 B</td></tr>
17+
<tbody><tr><td style="width:100%"><code>Direct_Command</code></td><td style="text-align:right;white-space:nowrap">2.818 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
18+
<tr><td style="width:100%"><code>MediatorNet_Command</code></td><td style="text-align:right;white-space:nowrap">9.130 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
19+
<tr><td style="width:100%"><code>Foundatio_Command</code></td><td style="text-align:right;white-space:nowrap">15.698 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
20+
<tr><td style="width:100%"><code>MediatR_Command</code></td><td style="text-align:right;white-space:nowrap">36.446 ns</td><td style="text-align:right;white-space:nowrap">128 B</td></tr>
21+
<tr><td style="width:100%"><code>Wolverine_Command</code></td><td style="text-align:right;white-space:nowrap">172.840 ns</td><td style="text-align:right;white-space:nowrap">704 B</td></tr>
22+
<tr><td style="width:100%"><code>MassTransit_Command</code></td><td style="text-align:right;white-space:nowrap">1,261.958 ns</td><td style="text-align:right;white-space:nowrap">4,192 B</td></tr>
2323
</tbody>
2424
</table>
2525

@@ -31,12 +31,12 @@ Request/response dispatch returning an Order object.
3131
<thead>
3232
<tr><th style="text-align:left">Method</th><th style="text-align:right;white-space:nowrap">Mean</th><th style="text-align:right;white-space:nowrap">Allocated</th></tr>
3333
</thead>
34-
<tbody><tr><td style="width:100%"><code>Direct_Query</code></td><td style="text-align:right;white-space:nowrap">31.557 ns</td><td style="text-align:right;white-space:nowrap">120 B</td></tr>
35-
<tr><td style="width:100%"><code>Foundatio_Query</code></td><td style="text-align:right;white-space:nowrap">31.946 ns</td><td style="text-align:right;white-space:nowrap">120 B</td></tr>
36-
<tr><td style="width:100%"><code>MediatorNet_Query</code></td><td style="text-align:right;white-space:nowrap">40.284 ns</td><td style="text-align:right;white-space:nowrap">120 B</td></tr>
37-
<tr><td style="width:100%"><code>MediatR_Query</code></td><td style="text-align:right;white-space:nowrap">77.069 ns</td><td style="text-align:right;white-space:nowrap">320 B</td></tr>
38-
<tr><td style="width:100%"><code>Wolverine_Query</code></td><td style="text-align:right;white-space:nowrap">335.164 ns</td><td style="text-align:right;white-space:nowrap">1,000 B</td></tr>
39-
<tr><td style="width:100%"><code>MassTransit_Query</code></td><td style="text-align:right;white-space:nowrap">6,436.008 ns</td><td style="text-align:right;white-space:nowrap">12,497 B</td></tr>
34+
<tbody><tr><td style="width:100%"><code>Direct_Query</code></td><td style="text-align:right;white-space:nowrap">25.439 ns</td><td style="text-align:right;white-space:nowrap">120 B</td></tr>
35+
<tr><td style="width:100%"><code>MediatorNet_Query</code></td><td style="text-align:right;white-space:nowrap">32.873 ns</td><td style="text-align:right;white-space:nowrap">120 B</td></tr>
36+
<tr><td style="width:100%"><code>Foundatio_Query</code></td><td style="text-align:right;white-space:nowrap">40.079 ns</td><td style="text-align:right;white-space:nowrap">120 B</td></tr>
37+
<tr><td style="width:100%"><code>MediatR_Query</code></td><td style="text-align:right;white-space:nowrap">56.719 ns</td><td style="text-align:right;white-space:nowrap">320 B</td></tr>
38+
<tr><td style="width:100%"><code>Wolverine_Query</code></td><td style="text-align:right;white-space:nowrap">243.265 ns</td><td style="text-align:right;white-space:nowrap">1,000 B</td></tr>
39+
<tr><td style="width:100%"><code>MassTransit_Query</code></td><td style="text-align:right;white-space:nowrap">4,711.686 ns</td><td style="text-align:right;white-space:nowrap">12,496 B</td></tr>
4040
</tbody>
4141
</table>
4242

@@ -48,12 +48,12 @@ Notification dispatched to 2 handlers.
4848
<thead>
4949
<tr><th style="text-align:left">Method</th><th style="text-align:right;white-space:nowrap">Mean</th><th style="text-align:right;white-space:nowrap">Allocated</th></tr>
5050
</thead>
51-
<tbody><tr><td style="width:100%"><code>Direct_Publish</code></td><td style="text-align:right;white-space:nowrap">4.265 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
52-
<tr><td style="width:100%"><code>MediatorNet_Publish</code></td><td style="text-align:right;white-space:nowrap">14.959 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
53-
<tr><td style="width:100%"><code>Foundatio_Publish</code></td><td style="text-align:right;white-space:nowrap">21.383 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
54-
<tr><td style="width:100%"><code>MediatR_Publish</code></td><td style="text-align:right;white-space:nowrap">129.381 ns</td><td style="text-align:right;white-space:nowrap">792 B</td></tr>
55-
<tr><td style="width:100%"><code>Wolverine_Publish</code></td><td style="text-align:right;white-space:nowrap">2,371.862 ns</td><td style="text-align:right;white-space:nowrap">2,840 B</td></tr>
56-
<tr><td style="width:100%"><code>MassTransit_Publish</code></td><td style="text-align:right;white-space:nowrap">2,701.091 ns</td><td style="text-align:right;white-space:nowrap">6,016 B</td></tr>
51+
<tbody><tr><td style="width:100%"><code>Direct_Publish</code></td><td style="text-align:right;white-space:nowrap">2.890 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
52+
<tr><td style="width:100%"><code>MediatorNet_Publish</code></td><td style="text-align:right;white-space:nowrap">10.210 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
53+
<tr><td style="width:100%"><code>Foundatio_Publish</code></td><td style="text-align:right;white-space:nowrap">32.287 ns</td><td style="text-align:right;white-space:nowrap">0 B</td></tr>
54+
<tr><td style="width:100%"><code>MediatR_Publish</code></td><td style="text-align:right;white-space:nowrap">88.472 ns</td><td style="text-align:right;white-space:nowrap">792 B</td></tr>
55+
<tr><td style="width:100%"><code>Wolverine_Publish</code></td><td style="text-align:right;white-space:nowrap">1,716.843 ns</td><td style="text-align:right;white-space:nowrap">2,840 B</td></tr>
56+
<tr><td style="width:100%"><code>MassTransit_Publish</code></td><td style="text-align:right;white-space:nowrap">1,925.750 ns</td><td style="text-align:right;white-space:nowrap">6,016 B</td></tr>
5757
</tbody>
5858
</table>
5959

@@ -65,12 +65,12 @@ Query where handler has an injected service (IOrderService) and timing middlewar
6565
<thead>
6666
<tr><th style="text-align:left">Method</th><th style="text-align:right;white-space:nowrap">Mean</th><th style="text-align:right;white-space:nowrap">Allocated</th></tr>
6767
</thead>
68-
<tbody><tr><td style="width:100%"><code>MediatorNet_FullQuery</code></td><td style="text-align:right;white-space:nowrap">55.357 ns</td><td style="text-align:right;white-space:nowrap">192 B</td></tr>
69-
<tr><td style="width:100%"><code>Direct_FullQuery</code></td><td style="text-align:right;white-space:nowrap">85.645 ns</td><td style="text-align:right;white-space:nowrap">304 B</td></tr>
70-
<tr><td style="width:100%"><code>MediatR_FullQuery</code></td><td style="text-align:right;white-space:nowrap">179.436 ns</td><td style="text-align:right;white-space:nowrap">744 B</td></tr>
71-
<tr><td style="width:100%"><code>Foundatio_FullQuery</code></td><td style="text-align:right;white-space:nowrap">252.710 ns</td><td style="text-align:right;white-space:nowrap">776 B</td></tr>
72-
<tr><td style="width:100%"><code>Wolverine_FullQuery</code></td><td style="text-align:right;white-space:nowrap">377.998 ns</td><td style="text-align:right;white-space:nowrap">1,000 B</td></tr>
73-
<tr><td style="width:100%"><code>MassTransit_FullQuery</code></td><td style="text-align:right;white-space:nowrap">6,304.521 ns</td><td style="text-align:right;white-space:nowrap">12,569 B</td></tr>
68+
<tbody><tr><td style="width:100%"><code>MediatorNet_FullQuery</code></td><td style="text-align:right;white-space:nowrap">40.075 ns</td><td style="text-align:right;white-space:nowrap">192 B</td></tr>
69+
<tr><td style="width:100%"><code>Direct_FullQuery</code></td><td style="text-align:right;white-space:nowrap">66.235 ns</td><td style="text-align:right;white-space:nowrap">304 B</td></tr>
70+
<tr><td style="width:100%"><code>MediatR_FullQuery</code></td><td style="text-align:right;white-space:nowrap">134.765 ns</td><td style="text-align:right;white-space:nowrap">744 B</td></tr>
71+
<tr><td style="width:100%"><code>Foundatio_FullQuery</code></td><td style="text-align:right;white-space:nowrap">183.770 ns</td><td style="text-align:right;white-space:nowrap">752 B</td></tr>
72+
<tr><td style="width:100%"><code>Wolverine_FullQuery</code></td><td style="text-align:right;white-space:nowrap">258.525 ns</td><td style="text-align:right;white-space:nowrap">1,000 B</td></tr>
73+
<tr><td style="width:100%"><code>MassTransit_FullQuery</code></td><td style="text-align:right;white-space:nowrap">5,635.649 ns</td><td style="text-align:right;white-space:nowrap">12,568 B</td></tr>
7474
</tbody>
7575
</table>
7676

@@ -82,12 +82,12 @@ CreateOrder returns an Order and publishes OrderCreatedEvent to 2 handlers. Foun
8282
<thead>
8383
<tr><th style="text-align:left">Method</th><th style="text-align:right;white-space:nowrap">Mean</th><th style="text-align:right;white-space:nowrap">Allocated</th></tr>
8484
</thead>
85-
<tbody><tr><td style="width:100%"><code>Direct_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">30.657 ns</td><td style="text-align:right;white-space:nowrap">144 B</td></tr>
86-
<tr><td style="width:100%"><code>MediatorNet_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">47.621 ns</td><td style="text-align:right;white-space:nowrap">144 B</td></tr>
87-
<tr><td style="width:100%"><code>Foundatio_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">124.632 ns</td><td style="text-align:right;white-space:nowrap">344 B</td></tr>
88-
<tr><td style="width:100%"><code>MediatR_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">167.340 ns</td><td style="text-align:right;white-space:nowrap">1,168 B</td></tr>
89-
<tr><td style="width:100%"><code>Wolverine_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">2,396.809 ns</td><td style="text-align:right;white-space:nowrap">4,064 B</td></tr>
90-
<tr><td style="width:100%"><code>MassTransit_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">7,880.173 ns</td><td style="text-align:right;white-space:nowrap">18,762 B</td></tr>
85+
<tbody><tr><td style="width:100%"><code>Direct_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">27.889 ns</td><td style="text-align:right;white-space:nowrap">144 B</td></tr>
86+
<tr><td style="width:100%"><code>MediatorNet_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">44.104 ns</td><td style="text-align:right;white-space:nowrap">144 B</td></tr>
87+
<tr><td style="width:100%"><code>Foundatio_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">92.445 ns</td><td style="text-align:right;white-space:nowrap">144 B</td></tr>
88+
<tr><td style="width:100%"><code>MediatR_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">157.323 ns</td><td style="text-align:right;white-space:nowrap">1,168 B</td></tr>
89+
<tr><td style="width:100%"><code>Wolverine_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">2,253.890 ns</td><td style="text-align:right;white-space:nowrap">4,064 B</td></tr>
90+
<tr><td style="width:100%"><code>MassTransit_CascadingMessages</code></td><td style="text-align:right;white-space:nowrap">7,338.962 ns</td><td style="text-align:right;white-space:nowrap">18,762 B</td></tr>
9191
</tbody>
9292
</table>
9393

@@ -99,12 +99,12 @@ Middleware returns cached result; handler is never invoked. Each library uses it
9999
<thead>
100100
<tr><th style="text-align:left">Method</th><th style="text-align:right;white-space:nowrap">Mean</th><th style="text-align:right;white-space:nowrap">Allocated</th></tr>
101101
</thead>
102-
<tbody><tr><td style="width:100%"><code>Direct_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">3.099 ns</td><td style="text-align:right;white-space:nowrap">72 B</td></tr>
103-
<tr><td style="width:100%"><code>MediatorNet_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">13.787 ns</td><td style="text-align:right;white-space:nowrap">72 B</td></tr>
104-
<tr><td style="width:100%"><code>MediatR_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">58.267 ns</td><td style="text-align:right;white-space:nowrap">488 B</td></tr>
105-
<tr><td style="width:100%"><code>Foundatio_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">69.557 ns</td><td style="text-align:right;white-space:nowrap">368 B</td></tr>
106-
<tr><td style="width:100%"><code>Wolverine_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">204.296 ns</td><td style="text-align:right;white-space:nowrap">752 B</td></tr>
107-
<tr><td style="width:100%"><code>MassTransit_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">5,063.661 ns</td><td style="text-align:right;white-space:nowrap">12,448 B</td></tr>
102+
<tbody><tr><td style="width:100%"><code>Direct_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">2.767 ns</td><td style="text-align:right;white-space:nowrap">72 B</td></tr>
103+
<tr><td style="width:100%"><code>MediatorNet_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">12.924 ns</td><td style="text-align:right;white-space:nowrap">72 B</td></tr>
104+
<tr><td style="width:100%"><code>Foundatio_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">28.396 ns</td><td style="text-align:right;white-space:nowrap">168 B</td></tr>
105+
<tr><td style="width:100%"><code>MediatR_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">56.364 ns</td><td style="text-align:right;white-space:nowrap">488 B</td></tr>
106+
<tr><td style="width:100%"><code>Wolverine_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">196.974 ns</td><td style="text-align:right;white-space:nowrap">752 B</td></tr>
107+
<tr><td style="width:100%"><code>MassTransit_ShortCircuit</code></td><td style="text-align:right;white-space:nowrap">5,558.044 ns</td><td style="text-align:right;white-space:nowrap">12,448 B</td></tr>
108108
</tbody>
109109
</table>
110110

samples/ModularMonolithSample/src/Orders.Module/Handlers/OrderEventHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Orders.Module.Handlers;
55

66
public class OrderEventHandler(ILogger<OrderEventHandler> logger)
77
{
8-
public Task HandleAsync(OrderCreated evt)
8+
public Task HandleAsync(OrderCreated evt, CancellationToken cancellationToken)
99
{
1010
logger.LogInformation("Order {OrderId} created for customer {CustomerId} with amount {Amount:C}",
1111
evt.OrderId, evt.CustomerId, evt.Amount);

samples/ModularMonolithSample/src/Orders.Module/Orders.Module.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
<MediatorHandlerLifetime>None</MediatorHandlerLifetime>
1212
<MediatorDisableInterceptors>false</MediatorDisableInterceptors>
1313
<MediatorDisableOpenTelemetry>false</MediatorDisableOpenTelemetry>
14+
<MediatorEnableGenerationCounter>true</MediatorEnableGenerationCounter>
1415
</PropertyGroup>
1516

1617
<ItemGroup>
1718
<CompilerVisibleProperty Include="MediatorDisableInterceptors" />
1819
<CompilerVisibleProperty Include="MediatorHandlerLifetime" />
1920
<CompilerVisibleProperty Include="MediatorDisableOpenTelemetry" />
21+
<CompilerVisibleProperty Include="MediatorEnableGenerationCounter" />
2022
<!-- Exclude the output of source generators from the compilation -->
2123
<Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
2224
<Content Include="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />

samples/ModularMonolithSample/src/Products.Module/Products.Module.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
<MediatorHandlerLifetime>None</MediatorHandlerLifetime>
1212
<MediatorDisableInterceptors>false</MediatorDisableInterceptors>
1313
<MediatorDisableOpenTelemetry>false</MediatorDisableOpenTelemetry>
14+
<MediatorEnableGenerationCounter>true</MediatorEnableGenerationCounter>
1415
</PropertyGroup>
1516

1617
<ItemGroup>
1718
<CompilerVisibleProperty Include="MediatorDisableInterceptors" />
1819
<CompilerVisibleProperty Include="MediatorHandlerLifetime" />
1920
<CompilerVisibleProperty Include="MediatorDisableOpenTelemetry" />
21+
<CompilerVisibleProperty Include="MediatorEnableGenerationCounter" />
2022
<!-- Exclude the output of source generators from the compilation -->
2123
<Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
2224
<Content Include="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />

samples/ModularMonolithSample/src/WebApp/WebApp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
<MediatorHandlerLifetime>None</MediatorHandlerLifetime>
1212
<MediatorDisableInterceptors>false</MediatorDisableInterceptors>
1313
<MediatorDisableOpenTelemetry>false</MediatorDisableOpenTelemetry>
14+
<MediatorEnableGenerationCounter>true</MediatorEnableGenerationCounter>
1415
</PropertyGroup>
1516

1617
<ItemGroup>
1718
<CompilerVisibleProperty Include="MediatorDisableInterceptors" />
1819
<CompilerVisibleProperty Include="MediatorHandlerLifetime" />
1920
<CompilerVisibleProperty Include="MediatorDisableOpenTelemetry" />
21+
<CompilerVisibleProperty Include="MediatorEnableGenerationCounter" />
2022
<!-- Exclude the output of source generators from the compilation -->
2123
<Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
2224
<Content Include="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />

src/Foundatio.Mediator.Abstractions/MediatorExtensions.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,21 @@ public MediatorConfigurationBuilder UseForeachAwaitPublisher()
135135
/// Uses the TaskWhenAllPublisher for the mediator.
136136
/// </summary>
137137
/// <returns></returns>
138-
public MediatorConfigurationBuilder TaskWhenAllPublisher()
138+
public MediatorConfigurationBuilder UseTaskWhenAllPublisher()
139139
{
140140
_configuration.NotificationPublisher = new TaskWhenAllPublisher();
141141
return this;
142142
}
143143

144+
/// <summary>
145+
/// Uses the FireAndForgetPublisher for the mediator.
146+
/// </summary>
147+
/// <returns></returns>
148+
public MediatorConfigurationBuilder UseFireAndForgetPublisher()
149+
{
150+
_configuration.NotificationPublisher = new FireAndForgetPublisher();
151+
return this;
152+
}
153+
144154
public MediatorConfiguration Build() => _configuration;
145155
}

0 commit comments

Comments
 (0)