44[ ![ NuGet] ( https://img.shields.io/nuget/dt/DispatchR.Mediator.svg )] ( https://www.nuget.org/packages/DispatchR.Mediator )
55[ ![ NuGet] ( https://img.shields.io/nuget/vpre/DispatchR.Mediator.svg )] ( https://www.nuget.org/packages/DispatchR.Mediator )
66
7- ### A High-Performance Mediator Implementation for .NET :trollface:
7+ ### A High-Performance Mediator Implementation for .NET :trollface:
88** * Minimal memory footprint. Blazing-fast execution.* **
99
1010> [ !NOTE]
1717- Allocates nothing on the heap — ideal for high-throughput scenarios
1818- Outperforms existing solutions in most real-world benchmarks
1919- Seamlessly compatible with MediatR — migrate with minimal effort
20+ - Include or exclude a set of handlers from an assembly — ideal for use with Aspire
2021- Currently supports
21- 1 . Simple Request:
22- 1 . ` IRequest<TRquest, TResponse> `
23- 2 . ` IRequestHandler<TRequest, TResponse> `
24- 3 . ` IPipelineBehavior<TRequest, TResponse> `
25- 2 . Stream Request:
26- 1 . ` IStreamRequest<TRquest, TResponse> `
27- 2 . ` IStreamRequestHandler<TRequest, TResponse> `
28- 3 . ` IStreamPipelineBehavior<TRequest, TResponse> `
29- 3 . Notifications:
30- 1 . ` INotification `
31- 2 . ` INotificationHandler<TRequestEvent> `
22+ 1 . Simple Request:
23+ 1 . ` IRequest<TRquest, TResponse> `
24+ 2 . ` IRequestHandler<TRequest, TResponse> `
25+ 3 . ` IPipelineBehavior<TRequest, TResponse> `
26+ 2 . Stream Request:
27+ 1 . ` IStreamRequest<TRquest, TResponse> `
28+ 2 . ` IStreamRequestHandler<TRequest, TResponse> `
29+ 3 . ` IStreamPipelineBehavior<TRequest, TResponse> `
30+ 3 . Notifications:
31+ 1 . ` INotification `
32+ 2 . ` INotificationHandler<TRequestEvent> `
3233> :bulb : ** Tip:** * If you're looking for a mediator with the raw performance of hand-written code, DispatchR is built for you.*
3334
3435# Syntax Comparison: DispatchR vs MediatR
@@ -44,8 +45,8 @@ public sealed class PingMediatR : IRequest<int> { }
4445
4546### DispatchR
46471 . Sending ` TRequest ` to ` IRequest `
47- 2 . Precise selection of output for both ` async ` and ` sync ` handlers
48- 1 . Ability to choose between ` Task ` and ` ValueTask `
48+ 2 . Precise selection of output for both ` async ` and ` sync ` handlers
49+ 1 . Ability to choose between ` Task ` and ` ValueTask `
4950
5051``` csharp
5152public sealed class PingDispatchR : IRequest <PingDispatchR , ValueTask <int >> { }
@@ -108,7 +109,7 @@ public sealed class LoggingBehaviorDispatchR : IPipelineBehavior<PingDispatchR,
1081091 . For every kind of return type — ` Task ` , ` ValueTask ` , or synchronous methods — you need to write a generic pipeline behavior. However, you don't need a separate pipeline for each request. As shown in the code below, this is a GenericPipeline for requests that return a ` ValueTask ` .
109110``` csharp
110111public class GenericPipelineBehavior <TRequest , TResponse >() : IPipelineBehavior <TRequest , ValueTask <TResponse >>
111- where TRequest : class , IRequest <TRequest , ValueTask <TResponse >>, new ()
112+ where TRequest : class , IRequest <TRequest , ValueTask <TResponse >>
112113{
113114 public required IRequestHandler <TRequest , ValueTask <TResponse >> NextPipeline { get ; set ; }
114115
@@ -206,7 +207,7 @@ public sealed class CounterPipelineStreamHandler : IStreamPipelineBehavior<Count
206207#### Generic stream pipeline behavior DispatchR
207208``` csharp
208209public class GenericStreamPipelineBehavior <TRequest , TResponse >() : IStreamPipelineBehavior <TRequest , TResponse >
209- where TRequest : class , IStreamRequest <TRequest , TResponse >, new ()
210+ where TRequest : class , IStreamRequest <TRequest , TResponse >
210211{
211212 public IStreamRequestHandler <TRequest , TResponse > NextPipeline { get ; set ; }
212213
@@ -261,7 +262,7 @@ public sealed class EventHandler(ILogger<Event> logger) : INotificationHandler<E
261262
262263``` csharp
263264public TResponse Send <TRequest , TResponse >(IRequest < TRequest , TResponse > request ,
264- CancellationToken cancellationToken ) where TRequest : class, IRequest, new()
265+ CancellationToken cancellationToken ) where TRequest : class, IRequest
265266{
266267 return serviceProvider
267268 .GetRequiredService<IRequestHandler<TRequest, TResponse>>()
@@ -273,7 +274,7 @@ public TResponse Send<TRequest, TResponse>(IRequest<TRequest, TResponse> request
273274
274275``` csharp
275276public IAsyncEnumerable < TResponse > CreateStream <TRequest , TResponse >(IStreamRequest < TRequest , TResponse > request ,
276- CancellationToken cancellationToken ) where TRequest : class, IStreamRequest, new()
277+ CancellationToken cancellationToken ) where TRequest : class, IStreamRequest
277278{
278279 return serviceProvider.GetRequiredService<IStreamRequestHandler<TRequest, TResponse>>()
279280 .Handle (Unsafe.As<TRequest>(request), cancellationToken);
@@ -301,9 +302,9 @@ public async ValueTask Publish<TNotification>(TNotification request, Cancellatio
301302```
302303
303304But the real magic happens behind the scenes when DI resolves the handler dependency:
304- > 💡 __ Tips:__
305+ > 💡 __ Tips:__
305306> 1 . * We cache the handler using DI, so in scoped scenarios, the object is constructed only once and reused afterward.*
306- >
307+ >
307308> 2 . * In terms of Dependency Injection (DI), everything in Requests is an IRequestHandler, it's just the keys that differ.
308309 When you request a specific key, a set of 1+N objects is returned: the first one is the actual handler, and the rest are the pipeline behaviors.*
309310
@@ -333,7 +334,10 @@ It's simple! Just use the following code:
333334builder .Services .AddDispatchR (typeof (MyCommand ).Assembly , withPipelines : true , withNotifications : true );
334335```
335336This code will automatically register all pipelines by default.
336- If you need to register them in a specific order, you could pass the Order via ConfigurationOptions like in the sample below:
337+ If you need to register them in a specific order, you can pass the order via ConfigurationOptions, as shown in the example below.
338+ <br >
339+ Additionally, you can include or exclude specific handlers from an assembly — which is especially useful when working with Aspire.
340+ You can also check the Samples section to see the Aspire-specific example.
337341``` csharp
338342builder .Services .AddDispatchR (options =>
339343{
@@ -346,6 +350,8 @@ builder.Services.AddDispatchR(options =>
346350 typeof (DispatchRSample .SecondPipelineBehavior ),
347351 typeof (DispatchRSample .GenericPipelineBehavior <,>)
348352 ];
353+ options .IncludeHandlers = [];
354+ options .ExcludeHandlers = [];
349355});
350356```
351357
@@ -390,13 +396,13 @@ Version 3 of Mediator Source Generator was excluded due to significantly lower p
390396
391397## ✨ Contribute & Help Grow This Package! ✨
392398We welcome contributions to make this package even better! ❤️
393- - Found a bug? → Open an issue
394- - Have an idea? → Suggest a feature
395- - Want to code? → Submit a PR
399+ - Found a bug? → Open an issue
400+ - Have an idea? → Suggest a feature
401+ - Want to code? → Submit a PR
396402
397403## Star History
398404<a href =" https://www.star-history.com/#hasanxdev/DispatchR&Timeline " >
399405 <img src =" https://api.star-history.com/svg?repos=hasanxdev/DispatchR&type=Timeline " width =" 400 " />
400406</a >
401407
402- Let's build something amazing together! 🚀
408+ Let's build something amazing together! 🚀
0 commit comments