Skip to content

Commit 84e71d3

Browse files
authored
Update README.md for v1.3.1 (#26)
1 parent 3ed8001 commit 84e71d3

4 files changed

Lines changed: 35 additions & 27 deletions

File tree

README.md

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
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]
@@ -17,18 +17,19 @@
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
4647
1. 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
5152
public sealed class PingDispatchR : IRequest<PingDispatchR, ValueTask<int>> { }
@@ -108,7 +109,7 @@ public sealed class LoggingBehaviorDispatchR : IPipelineBehavior<PingDispatchR,
108109
1. 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
110111
public 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
208209
public 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
263264
public 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
275276
public 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

303304
But 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:
333334
builder.Services.AddDispatchR(typeof(MyCommand).Assembly, withPipelines: true, withNotifications: true);
334335
```
335336
This 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
338342
builder.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! ✨
392398
We 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! 🚀

src/Sample/DispatchR/SendRequest/GenericPipelineBehavior.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace Sample.DispatchR.SendRequest;
44

55
public class GenericPipelineBehavior<TRequest, TResponse>(ILogger<GenericPipelineBehavior<TRequest, TResponse>> logger)
66
: IPipelineBehavior<TRequest, ValueTask<TResponse>>
7-
where TRequest : class, IRequest<TRequest, ValueTask<TResponse>>, new()
7+
where TRequest : class, IRequest<TRequest, ValueTask<TResponse>>
88
{
99
public ValueTask<TResponse> Handle(TRequest request, CancellationToken cancellationToken)
1010
{

src/Sample/DispatchR/StreamRequest/GenericPipelineBehavior.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Sample.DispatchR.StreamRequest;
55

66
public class GenericPipelineBehavior<TRequest, TResponse>(ILogger<GenericPipelineBehavior<TRequest, TResponse>> logger)
77
: IStreamPipelineBehavior<TRequest, TResponse>
8-
where TRequest : class, IStreamRequest<TRequest, TResponse>, new()
8+
where TRequest : class, IStreamRequest<TRequest, TResponse>
99
{
1010
public async IAsyncEnumerable<TResponse> Handle(TRequest request, CancellationToken cancellationToken)
1111
{

src/Sample/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
typeof(DispatchRSample.SecondPipelineBehavior),
3535
typeof(DispatchRSample.GenericPipelineBehavior<,>)
3636
];
37+
options.IncludeHandlers = [];
38+
options.ExcludeHandlers = [];
3739
});
3840

3941
var app = builder.Build();

0 commit comments

Comments
 (0)